---
# System prepended metadata

title: 期末考總整理

---

# 期末考總整理

沒有編譯器?這好用

{%preview https://www.onlinegdb.com/ %}

## 複習/技巧

### 1. ==左出右進==  這很重要

一堆人都會搞混，切記`cout <<`與`cin >>`!
然後要記得`std::`或`using namespace std;`。

### 2.加減乘除不能省，電腦很笨(但知道四則運算)

example:

```cpp=
int a = 5, b = 6;
cout << ab << endl;
```

~~~
error(電腦不知道ab是什麼變數!)
~~~

正解：

```cpp=
int a = 5, b = 6;
cout << a * b << endl;
```

~~~
30
~~~

### 3.清文沒教的實用東東:布林值
~~是說那個林O浩的邏輯不太好，充要必要還不會(笑)~~

跟`int`/`float`一樣是一種資料型態，但只有`true`跟`false`兩種可能，對應到數字就是非零為`true`零為`false`。再邏輯中條件回傳的就是布林。
example:

```cpp=
int a = 0;
if (a == 1) { // 回傳false
  cout << "case1" << endl;
}
else {
  cout << "case2" << endl;
}
```

~~~
case2
~~~

當然，也可以自己設
example:

```cpp=
bool a = true; // 也可以寫bool a = 1;
if (a == true) {  //true，也可以簡寫為if(a)有同樣效果
  cout << "case1" << endl;
}
else {
  cout << "case2" << endl;
}

```

~~~
case1
~~~

### 4. = 與 ==

一個=是"指定"，兩個=才是真正的"等於"，你各位期中考多少人死在這自己自首!(笑
example:

```cpp=
int a = 0;
if (a = 1){ //1是true
  cout << "case1" << endl;
}
else {
  cout << "case2" << endl;
}
```

~~~
case1
~~~

因為a被指定成1了，非零者皆為真，所以才會變case1。
不過大於跟小於只有一個!! 兩個會變位元運算符(對，又一個清文沒說的東東)

ps那如果是大於等於跟小於等於呢?答案是`>=` `<=`。怕搞混也可以用`||`弄成等於或小於(大於)的形式。

### 5. `!` 的功能

`!`是做反轉功能，就是邏輯裡的"非"，所以`!=`就是不等於，絕對跟階乘沒有關係，切勿排組做到走火入魔!
example:

```cpp=
int a = 5;
if (a == 0) {
  cout << "case1" << endl;
}
if (a != 0) {
  cout << "case2" << endl;
}
```

~~~
case2
~~~

### 6.`return 0;`的意義

這是函式的概念，反正記得在main裡面用的話會中止整個程式。
當然，保險起見有的話是最好。

### 7.一行程式的結尾`;`

C++不是看換行斷句是看分號! 除了預處理命令(`#`開頭)都要加。

## 期末考範圍:迴圈/陣列

### 迴圈
那個叫林什麼浩的不會迴圈是不是~ (這我可以笑三年)

### 1.`for`:可以重複執行子區域內的程式碼

```mermaid
graph TD
for-->初始式;
初始式-->判斷式;
判斷式-->False;
False---->迴圈下之程式;
判斷式-->True;
True-->陳述句;
陳述句-->遞增式;
遞增式-->判斷式;
```

直接看範例:
example:

```cpp=
int a = 5;
for (int i = 0; i < 5; i++) {
  a++; // 就是a += 1;
}
cout << a << endl;
```

~~~
10
~~~

重複五次加一。

ps: 在for控制敘述內(括號內)才宣告的迴圈變數(通常是i) **有效區域只有那個for裡面!!**
這個概念之後有緣再來聊，反正如果想要保留i的話必須在for之外宣告。
example:

```cpp=
int a = 5;
int i;
for (i = 0; i < 5; i++) {
  a++;
}
cout << i << endl;
```

~~~
5
~~~

但如果這樣就錯，因為找不到i。
```cpp=
int a = 5;
for (int i = 0; i < 5; i++) {
  a++;
}
cout << i << endl;
```

~~~
error (電腦已經不認識i了)
~~~

### 2.`while`:只要條件符合就一直重複

```mermaid
graph TD
while --> 條件式
條件式 --> True
條件式 --> False
True --> 重複執行之程式
重複執行之程式 --> 條件式
False ---> 迴圈下之程式
```

一樣直接看範例:
example:

```cpp=
int a = 5;
while (a < 11) {
  a++;
}
cout << a << endl;
```

~~~
11
~~~

也是重複五次加一，但是否停止取決於a自己。
example:

```cpp=
int a = 5;
while ( a > 11) {//進來時a是5，不合條件
  a++;
}
cout << a << endl;
```

~~~
5
~~~

這個while就完全沒有進去。

如果你想搞點事
example:

```cpp=
int a = 5, bool b = true;
while (b) {//true
  a++;
}
cout << a << endl;
```
```
                         (對，沒有輸出，因為沒有結束的時候)
```

可以直接寫：

```cpp=
int a = 5;
while (true) {
  a++;
}
cout << a << endl;
```

### 3.`do-while`:先做再判斷
```mermaid
graph TD
do-->重複執行之程式;
重複執行之程式-->條件式;
條件式-->True;
條件式-->False;
True-->重複執行之程式;
False-->迴圈下之程式;
```

其實沒有很好用
example:

```cpp=
int a = 5;
do {
  a++;
}
while (a > 11);
cout << a << endl;
```

~~~
6
~~~

理論上不該進這迴圈，但```do-while```強制讓他跑了一次
不過更建議複製貼上再執行while
example:

```cpp=
int a = 5;
a++;
while (a > 11) {
  a++;
}
cout << a << endl;
```

~~~
6
~~~

### 4.`break`跟`continue`:跳脫指令

有點玄，`break`是直接跳出迴圈，`continue`則是跳進下一輪迴圈。
請看範例
example:

```cpp=
int a = 5;
while ( a < 11) {
  a++;
  if (a == 8) {
    break;
  }
}
cout << a << endl;
```

~~~
8
~~~

到8就跳出來了。

```cpp=
int a = 5;
while ( a < 11) {
  a++;
  if (a == 8) {
    continue;
  }
  cout << a << endl;
}
```

~~~
6 7 9 10 11  
~~~

到8時`cout`會被無視。
==切記，只跳脫"迴圈"，即`for`跟`while`，`if`不是!==

## 陣列

### 1.陣列宣告

在宣告時用中括號表**長度(length)**，大括號表內容:
example:

```cpp=
int b[3];
int c[] = {1, 2, 3};
int d[5] = {1, 2, 3, 4, 5};
```

但切記，不可以既沒長度又沒內容(就像你各位的作文==)
example:

```cpp=
int a[];//這是違法的!!
```

因為電腦不知道要申請多少記憶體空間。

ps:當然，陣列也未必要是整數陣列，也可以```float a[5];```，
或```bool b[]={true,true,false}```之類。

### 2.陣列使用

在使用時，大括號內的數字是**索引值(index)**，20個人沒有第20號!!
example:

```cpp=
int c[] = {1, 2, 3};
cout << c[0] << " " << c[2] << endl;
```

~~~
1 3 
~~~

所以以下是錯誤的
example:

```cpp=
int c[] = {1, 2, 3};
cout << c[3] << endl;
```

~~~
error (沒有3號!) // 會輸出奇怪數字
~~~

### 迴圈配陣列

這個應用必考!~~我感覺我好像對話式~~
比如說輸出陣列內容或輸入，都可以用```for```搞定
example:

```cpp=
int n = 5;
int c[n];
for (int i = 0; i < n; i++) {
  c[i] = i;
}
for (int j = n - 1; j >= 0; j--) {
  cout << c[j] << " ";
}
```

~~~
4 3 2 1 0
~~~

## 那些清文沒檢討的題目

供參考

### 輸出三角形

example:
1

```cpp=
#include <iostream>
using namespace std;

int main() {
  for (int i = 1; i <= 5; i++) {
    for (int j = 0; j < i; j++) {
      cout << "*";
    }
    cout << endl;
  }
}
```

~~~
*
**
***
****
*****
~~~

2

```cpp=
#include <iostream>
using namespace std;

int main() {
  for (int i = 5; i > 0; i--) {
    for (int j = 0; j < i; j++) {
      cout << "*";
    }
    cout << endl;
  }
}
```

~~~
*****
****
***
**
*
~~~

3

```cpp=
#include <iostream>
using namespace std;

int main() {
  for (int i = 1; i <= 5; i++) {
    for (int j = 1; j < i; j++) {
      cout << " ";
    }
    for (int j = 0; j <= (5 - i); j++) {
      cout << "*";
    }
    cout << endl;
  }
}
```

~~~
*****
 ****
  ***
   **
    *
~~~

4

```cpp=
#include <iostream>
using namespace std;

int main() {
  for (int i = 1; i <= 9; i += 2) {
    for (int j = 0; j < (9 - i) / 2; j++) {
      cout << " ";
    }
    for (int j = 0; j < i; j++) {
      cout << "*";
    }
    cout << endl;
  }
}
```

~~~
    *    
   ***   
  *****  
 ******* 
*********
~~~

### 猜數字

example:

```cpp=
#include <iostream>
using namespace std;

int main(){
  int ans = 50;//任何數都可以
  int counter = 0, input;
  while (true) {
    cout << "enter num:";
    cin >> input;
    counter++;
    if (input < ans) {
      cout << "too small" << endl;
    }
    else if (input > ans) {
      cout << "too big" << endl;
    }
    else {
      break;
    }
  }
  cout<<"congratulation"<<endl<<"you tried "<<counter<< " times" << endl;
  return 0;
}
```

~~~
enter num:70
too big
enter num:30
too big
enter num:50
congratulation
you tried 3 times
~~~

## 稍微進階的概念 ~~(偷吃步)~~

### algorithm裡的工具:sort
用來做排序，由小到大;
這我在期中考那份有用過，拿來找資料很方便，比如說那題找出最高分
期中考那份:
{%preview https://hackmd.io/KDvSjVGrRbiWKpHEhOZlgQ %}
平凡人的寫法
example:
```cpp=
#include <iostream>
using namespace std;
int main(){
  int a[] = {3, 9, 2, 8, 1};
  int max = 0;
  for (int i = 0; i < 5; i++) {
    if (max < a[i]) {
      max = a[i];
    }
  }
  cout << max << endl;
}
```

~~~
9
~~~

高手的寫法(經柏上身)
example:

```cpp=
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
  int a[5] = {3, 9, 2, 8, 1};
  sort(a, a + 5);//排序範圍內的元素
  cout << a[4];
}
```

~~~
9
~~~

因為整個陣列被我換成了`{1,2,3,8,9}`，所以我只要抓最後一個就好。

可能有人會問為啥是加五?不是沒有`a[5]`這一項?
這是因為機制是範圍為頭到尾但不包含尾(左閉右開)，我只能說 先背吧。

### 隨機生成

可以讓電腦雖機丟數字給你，用剛剛那題猜數字來舉例
example:

```cpp=
#include <iostream>
#include <random>
#include <cstdlib>
using namespace std;

int main() {
  srand (time (NULL));//先背...這不好解釋
  int ans = (rand() % 100) + 1;//取亂數再限制範圍到1~100
  int counter = 0, input;
  while (true) {
    cout << "enter num:";
    cin >> input;
    counter++;
    if (input < ans) {
      cout << "too small" << endl;
    }
    else if (input > ans){
      cout << "too big" << endl;
    }
    else {
      cout<<"error"<<endl;
      return 0;  
    }
  }
  cout<<"congratulation"<<endl<<"you tried "<<counter<< " times" << endl;
}
```

其實這個亂數不是真正的亂數（偽隨機），但現在沒有很重要

## 練習題

有空可以來玩玩

### 1.(易)求總分平均

輸入五個整數，輸出總和與無條件捨去的平均值

```
10 20 30 40 50
```

```
150
30
```

### 2.(中)找最大與次大

第一格輸入是陣列大小n，之後n格輸入是陣列的每一個元素，求最大者與次大者。

```
6
20 50 10 40 30 45
```

```
50
45
```

### 3. (中)3N+1問題

輸入一整數，若為奇數則*3 + 1，偶數則 / 2，求出現的數形成之數列有幾項。

```
127
```

```
47
```

到這裡都應該還算期末考可能考的難度，再往下應該就不會了

### 4.(難)求孤單者

輸入9數(必然是一到五的整數)，其中四個數出現兩次，輸出唯一只出現一次的數

```
3 1 4 5 3 1 4 2 2
```

```
5
```

### 5.(更難)進階求孤單者

同上題，但輸入數之範圍擴大至非負整數。

```
6 20 9 8 9 71 20 8 6
```

```
71
```

## 總結

期末考比起其中會更刺激更有趣，尤其是陣列配迴圈的操作一定考爛。電腦不會猜你意思，請務必搞清楚迴圈變數和陣列索引的關聯。
==一定要練，一定要練，一定要練，看得懂不等於寫得出，多打才是真的學會。==

加油:)
![image](https://hackmd.io/_uploads/rkigl_Amgx.png)
