<style>
.reveal .slides {
font-size: 40px;
}
</style>
# 南大附中資訊研究社 NFIRC 1st
## 第 4 次社課講義
2023/11/22
主講:劉正宗 老師
----
## 課前準備
- 開好上課需要的頁面
- Discord
- Google Meet
- Replit
- Zero Judge
- 點名
- 社團積分
---
## 複習時間
- 變數
- 運算子
- 條件判斷式
----
## 變數大集合
| 名稱 | 寫法 | 備註 |
| ------- | -------- | -------- |
| 整數 | int | 範圍 $-2^{31}$ ~ $2^{31}-1$ |
| 較大的整數| long long| 範圍 $-2^{63} \sim 2^{63} - 1$|
| 浮點數 | double | 儲存非整數的時候使用 |
| 字元 | char | 以 '' 包住字元 |
| 字串 | string | 以 "" 包住字串 |
| 布林值 | bool | 僅有兩個值:true / false|
----
## 保留小數點的除法
- 強制轉型
寫法是括號內包住要轉變的型別

----
## 全域變數&區域變數

----
## bool 布林值
+ true == 1
+ false == 0
----
## 比較運算子
| 定義 | 運算子 | 解釋 |
| -------- |:------:|:--------------------------- |
| 相等 | == | a 與 b 相等 50 == 50 |
| 不相等 | != | a != b 就像 50 != 100 |
| 大於 | > | a > b 就像 100 > 50 |
| 小於 | < | a < b 就像 50 < 100 |
| 大於等於 | >= | a >= b 就像 100 >= 50 |
| 小於等於 | <= | a <= b 就像 50 >= 100 |
----
## 邏輯運算子
```typescript
或(OR): ||
且(AND): &&
相反(NOT): !
```
[詳細介紹文章 by SA](https://hackmd.io/@sa072686/cp/%2F%40sa072686%2FHkfY_rMur)
----
條件判斷式
```cpp=
#include <bits/stdc++.h>
using namespace std;
int main() {
int n; cin >> n;
if(n > 0) cout << 1 << "\n";
else if(n == 0) cout << 0 << "\n";
else cout << -1 << "\n";
return 0;
}
```
----
## 延伸知識
- [int 的範圍 溢位 開 long long](https://hackmd.io/@sa072686/cp/%2F%40sa072686%2FB1tr_OtOS)
- 有號無號 signed & unsigned
- INT_MIN, INT_MAX
- min( ), max( )
- 小數點後位數 setprecision( )
- [浮點數的誤差與應對](https://hackmd.io/@sa072686/cp/%2FcZfev35MRp-nFy_YII9wfg)
- 三元運算 (A ? B : C)
- [多條件判斷式 switch](https://openhome.cc/Gossip/CppGossip/switchStatement.html)
---
## 目錄
1. while 迴圈
2. for 迴圈
3. 迴圈控制 (continue、break)
4. 延伸知識
❗️原訂內容有教陣列 但因此次上課沒上完
所以目前已將陣列內容移到下一次第 5 次社課教
----
## 課前須知
此次上課相比之前的社課
會有更多的程式碼出現在講義中
希望培養大家閱讀程式碼的能力
試著理解每段 Code 的運作原理
能更有效提升你的程式能力
---
## 迴圈
1. while
2. for
----
## 迴圈是什麼?

重複執行
----
## 說 100 次 hello
```cpp=
#include <iostream>
using namespace std;
int main() {
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
cout << "hello\n";
return 0;
}
```
----
## 一定要複製 100 次嗎?
----
我們可以使用迴圈
讓電腦幫我們重複執行 100 次就好
不用我們自己複製 100 行程式碼
---
## while 迴圈
當條件成立時 重複執行直到條件不成立
```txt=
while(條件成立時) {
重複執行這段程式碼
}
條件不成立時 電腦會退出迴圈並接著執行下面的程式
```
----
## 如何用 while 迴圈說 100 次 hello
```cpp=
#include <iostream>
using namespace std;
int main() {
int t = 100;
while(t > 0) {
cout << "hello\n";
t--;
}
return 0;
}
```
----
## 無限迴圈

當條件永遠成立時 將會形成無限迴圈
----
## 重複無限次說 hello
```cpp=
#include <iostream>
using namespace std;
int main() {
while(true) {
cout << "hello\n";
}
return 0;
}
```
:::danger
請極力避免寫出無限迴圈
:::
----
## 如何避免寫出無限迴圈
### 修改前
```cpp=
#include <iostream>
using namespace std;
int main() {
int t = 100;
while(t > 0) {
cout << "hello\n";
}
return 0;
}
```
因為每次做完迴圈中的事後 t 並沒有改變
條件永遠成立 所以會無限重複做下去
----
### 修改後
```cpp=
#include <iostream>
using namespace std;
int main() {
int t = 100;
while(t > 0) {
cout << "hello\n";
t-- // 讓條件中的 t 每次都遞減 才有機會退出迴圈
}
return 0;
}
```
----
### 簡化版
```cpp=
#include <iostream>
using namespace std;
int main() {
int t = 100;
while(t--) {
cout << "hello\n";
}
return 0;
}
```
因為在上一堂課有教到 bool 布林值
true == 1
false == 0
當 t 逐漸遞減到 0 時
剛好就是條件不成立的 false
就會退出迴圈了
----
## 使用 while 讀取特定數量的輸入
有 n 個數字 請讀入那 n 個數字後 輸出總和
輸入
```txt
5
10 40 20 80 50
```
輸出
```txt
200
```
----
輸入
```txt
5
10 40 20 80 50
```
程式碼
```cpp=
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, a, sum = 0;
cin >> n;
while(n--) {
cin >> a;
sum += a;
}
cout << sum << "\n";
return 0;
}
```
----
當題目沒有說有幾個數字時
你該怎麼辦
```txt
10 40 20 80 50
```
輸出
```txt
200
```
----
## 重要技巧 EOF
EOF(End Of File)
當題目沒有限制有幾筆輸入時
我們只好重複輸入直到沒有輸入為止
此技巧在競程題目中常常出現
請務必學會
----
輸入
```txt
10 40 20 80 50
```
程式碼
```cpp=
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, sum = 0;
while(cin >> n) {
sum += n;
}
cout << sum << "\n";
return 0;
}
```
----
## 解釋
cin 這個函式其實是會回傳 bool 的
如果正確讀取到了整數會回傳 true
沒有讀取到東西就會回傳 false
所以我們把 cin 放在 while 的條件裡
剛好就能在沒有讀取到數字時退出迴圈
----
## 如何判斷整數有幾個位數
輸入 1
```txt
100
```
輸出 1
```txt
3
```
輸入 2
```txt
12345678
```
輸出 2
```txt
8
```
----
需運用到
1. while 迴圈
2. 除法
----
## 求位數程式碼
```cpp=
#include <bits/stdc++.h>
using namespace std;
int main() {
int n; cin >> n;
int digit = 0;
while(n != 0) {
n /= 10;
digit++;
}
cout << digit << "\n";
return 0;
}
```
---
## for 迴圈
重複執行特定次數
```txt
for(初始值; 判斷式; 改變值) {
重複執行這段程式碼
}
```
----
## 請輸出 1 ~ 10
如果沒學迴圈你可能會這樣寫
```cpp=
#include <iostream>
using namespace std;
int main() {
cout << 1 << " ";
cout << 2 << " ";
cout << 3 << " ";
cout << 4 << " ";
cout << 5 << " ";
cout << 6 << " ";
cout << 7 << " ";
cout << 8 << " ";
cout << 9 << " ";
cout << 10 << " ";
return 0;
}
```
----
## 用 for 迴圈解決
```cpp=
#include <iostream>
using namespace std;
int main() {
for(int i = 1; i <= 10; i++) {
cout << i << " ";
}
return 0;
}
```
----
## 請輸出 10 ~ 1
```cpp=
#include <iostream>
using namespace std;
int main() {
for(int i = 10; i > 0; i--) {
cout << i << " ";
}
return 0;
}
```
只需把 for 迴圈中的三個地方調整一下就好
1. 把初始值設成最後一個
2. 把判斷式改成 i > 0
3. 把變化量改為 遞減
----
## 如何用 for 迴圈說 100 次 hello
```cpp=
#include <bits/stdc++.h>
using namespace std;
int main() {
// 設 i 從 0 開始; 當 i < 100 時繼續執行; 每做完一次 i 就 +1
for(int i = 0; i < 100; i++) {
cout << "hello\n";
}
return 0;
}
```
----
## 如何在 n 個數字中找最大或最小值
輸入
```txt
5
55 16 40 84 136
```
輸出
```txt
max = 136
min = 16
```
----
各位可以聯想到利用上一節的延伸知識中
max()、min() 函數與 INT_MAX、INT_MIN
在每次的輸入後判斷最大最小值
----
程式碼
```cpp=
#include <iostream>
using namespace std;
int main() {
int maxn = INT_MIN, minn = INT_MAX;
int n,a;
cin >> n;
while(n--) {
cin >> a;
maxn = max(maxn, a);
minn = min(minn, a);
}
cout << "max = " << maxn << "\nmin = " << minn << "\n";
}
```
先把最大值設成一個很小的值 int maxn = INT_MIN
在每次輸入時都比較一次 maxn = max(maxn, a);
輸入完就會是最大值了 最小值同理
----
## 觀察到了嗎
迴圈其實就是把重複、單一、的事情
交給電腦重複跑 省時省力
---
## 迴圈的控制
- continue
- break
----
## 請輸出 1 ~ 10, 但不要輸出 n
如果 n == 3 請輸出
```
1 2 4 5 6 7 8 9 10
```
如果 n == 8 請輸出
```
1 2 3 4 5 6 7 9 10
```
思考一下該怎麼做呢?
----
## 用兩個迴圈?
```cpp=
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
for(int i = 1; i < n; i++) {
cout << i << " ";
}
for(int i = n+1; i <= 10; i++) {
cout << i << " ";
}
return 0;
}
```
----
太麻煩了 我們來學 continue
continue == 繼續(跳過此次)
----
## continue 實際應用
請輸出 1 ~ 10 但不要輸出 n
```cpp=
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
for(int i = 1; i <= 10; i++) {
if(i == n) {
continue;
}
cout << i << " ";
}
return 0;
}
```
----
## 請加總 1 ~ 10, 在超過 n 前就停止
如果 n == 8 請輸出
```
1 2 3
```
如果 n == 20 請輸出
```
1 2 3 4 5
```
思考一下該怎麼做呢?
----
n == 8
```cpp=
#include <iostream>
using namespace std;
int main() {
int n, sum = 0;
cin >> n;
for(int i = 1; i <= 10; i++) {
if(sum + i > n) {
break;
}
cout << i << " ";
sum += i;
}
return 0;
}
```
輸出
```
1 2 3
```
----
適當的運用迴圈與控制可以事半功倍
讓你寫程式更有效率、更有邏輯
---
## 延伸知識
- do-while 迴圈
----
## do-while 迴圈
- while:重複執行直到條件不成立
(當一開始條件不成立時就完全不會執行)
```cpp=
while(條件成立時) {
重複執行這段程式碼
}
```
- do-while:先執行一次再重複執行直到條件不成立
(必定會先執行一次 再決定是否繼續)
```cpp=
do {
程式碼
} while (條件成立時才繼續重複執行程式碼直到條件不成立);
```
----
## 使用 do-while 加總 1 ~ 100
```cpp=
#include <bits/stdc++.h>
using namespace std;
int main() {
int sum = 0, i = 1;
do {
sum += i;
i++;
} while (i <= 100);
cout << "1 + 2 + .... + 99 + 100 = " << sum << "\n";
return 0;
}
```
---
# 題單
## 必做
1. [d498 迴圈](https://zerojudge.tw/ShowProblem?problemid=d498)
2. [a104 陣列 排序](https://zerojudge.tw/ShowProblem?problemid=a104)
#
### [題解連結](https://nfirc.notion.site/c1db904ca8604f62918c204da938dc51?v=ff8e808739744ad8bb195ef63ee348f2&pvs=4)
---
## 回饋表單
https://forms.gle/ehJmT3hqKtnzQQk17

{"description":"2023/11/22主講:劉正宗 老師","slideOptions":"{\"parallaxBackgroundImage\":\"\",\"backgroundTransition\":\"none\",\"transition\":\"slide\",\"transitionSpeed\":\"slow\",\"controlsBackArrows\":\"faded\",\"spotlight\":{\"enabled\":false}}","showTags":"true","title":"第 4 次社課講義","contributors":"[{\"id\":\"a5e01884-520b-4df5-8e23-bfcc32fb4697\",\"add\":18293,\"del\":7535},{\"id\":\"133c1d63-1697-43cd-a9d9-860f755172d1\",\"add\":32,\"del\":4}]"}