### C程式設計導論
### for與while迴圈
---
<!-- .slide: data-transition="fade" -->
<h3 class="text-left">
Table of Contents
</h3>
- 認識迴圈結構
- while與for迴圈
- 巢狀迴圈
- 其他酷酷的迴圈操作
- 程式範例
- 例題練習
----
<!-- .slide: data-transition="fade" -->
### 為了節省講義空間
### 從這裡開始會習慣性省略以下幾行程式
```cpp
#include<stdio.h>
int main(){
return 0;
}
```
<!-- .element: class="fragment" data-fragment-index="1" -->
---
<!-- .slide: data-transition="fade" -->
### 認識迴圈結構
----
<!-- .slide: data-transition="fade" -->
**程式是寫給電腦的指令**
**當我們寫很多指令的時候**
<!-- .element: class="fragment" data-fragment-index="1" -->
**程式也會越亂越雜**
<!-- .element: class="fragment" data-fragment-index="2" -->
----
<!-- .slide: data-transition="fade" -->
**尤其是在寫重複的指令時常常會感到厭煩**
**例如說變數$n$加變數$a$共$100$次**
<!-- .element: class="fragment" data-fragment-index="1" -->
**我們用之前的方法來說 就要寫成下一頁那樣**
<!-- .element: class="fragment" data-fragment-index="2" -->
----
<!-- .slide: data-transition="fade" -->
```cpp
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
n += a;
```
**超級麻煩**
<!-- .element: class="fragment" data-fragment-index="1" -->
----
<!-- .slide: data-transition="fade" -->
**因此我們需要有一個指令來代表重複的動作**

----
<!-- .slide: data-transition="fade" -->
**除此之外**
**一個迴圈不可能永遠重複下去**
**因此我們需要設立一個運行的條件**
<!-- .element: class="fragment" data-fragment-index="1" -->
----
<!-- .slide: data-transition="fade" -->
**舉個例子**
**假設我們今天想把變數$a$乘$10$次數字$7$**
**並輸出結果$a$**
<!-- .element: class="fragment" data-fragment-index="1" -->
----
<!-- .slide: data-transition="fade" -->
**那我們就需要一個計數器cnt去紀錄到底做了幾次**
----
<!-- .slide: data-transition="fade" -->
**流程圖**
```mermaid
flowchart LR
st((開始)):::A
cnt1[cnt歸零]:::P
t1{cnt是否<10}:::K
t2[cnt=cnt+1]:::P
t3[a=a*7]:::P
a[輸出a]:::P
ed((結束)):::A
st --> cnt1 --> t1 --> |NO|a --> ed
t1 --> |YES|t2 --> t3 --> t1
classDef A stroke:#f00, fill:#fff
classDef K stroke:#0f0, fill:#fff
classDef P stroke:#00f, fill:#fff
```
---
<!-- .slide: data-transition="fade" -->
### while與for迴圈
----
<!-- .slide: data-transition="fade" -->
**接下來講一下迴圈在C語言的實現方式**
----
<!-- .slide: data-transition="fade" -->
**C語言的迴圈主要有兩種**
- **for迴圈**
- **while迴圈**
<!-- .element: class="fragment" data-fragment-index="1" -->
----
<!-- .slide: data-transition="fade" -->
<h3 class="text-left">
while迴圈語法
</h3>
```cpp
while(條件){
...程式敘述...
}
```
----
<!-- .slide: data-transition="fade" -->
<h3 class="text-left">
for迴圈語法
</h3>
```cpp
for(初值; 條件; 變數更新){
...程式敘述...
}
```
----
<!-- .slide: data-transition="fade" -->
**會發現for比while複雜一點**
**多了初值、變數更新**
<!-- .element: class="fragment" data-fragment-index="1" -->
----
<!-- .slide: data-transition="fade" -->
**for迴圈多出的這些東西可以當作計數器**
----
<!-- .slide: data-transition="fade" -->
**比如說剛剛的例子**
**變數$a$乘$10$次數字$7$並輸出**
<!-- .element: class="fragment" data-fragment-index="1" -->
```cpp
int a = 5, cnt;
for(cnt = 0; cnt < 10; cnt += 1){
a *= 7;
}
printf("%d", a);
```
----
<!-- .slide: data-transition="fade" -->
**當然也可以用while迴圈實現**
```cpp
int a = 5, cnt = 0;
while(cnt < 10){
a *= 7;
cnt += 1;
}
printf("%d", a);
```
----
<!-- .slide: data-transition="fade" -->
**小技巧**
**以下這部分**
```cpp
cnt += 1;
```
**可以寫成**
```cpp
cnt++;
```
----
<!-- .slide: data-transition="fade" -->
**小技巧**
```cpp
int i;
for(i = 0; i < n; i++)
```
**可以寫成**
```cpp
for(int i = 0; i < n; i++)
```
**這樣寫就會變成在迴圈裡宣告i**
**當離開迴圈 i就不能用了**
---
### 巢狀迴圈
----
<!-- .slide: data-transition="fade" -->
**巢狀迴圈就是把兩個迴圈疊在一起**
```cpp
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
for(int k = 0; k < o; k++){
...程式敘述...
}
}
}
```
**等等範例會碰到**
---
<!-- .slide: data-transition="fade" -->
### 其他酷酷的迴圈操作
----
<!-- .slide: data-transition="fade" -->
<h3 class="text-left">
End of File
</h3>
**有些題目可能會要求輸入到資料末尾**
**也就是End of File (簡稱EOF)**
**那輸入就可以這樣用while包著**
```cpp
while(scanf("%d", &n) != EOF){
// 程式內容寫這邊~
}
```
----
<!-- .slide: data-transition="fade" -->
<h3 class="text-left">
取最大值
</h3>
**先初始化一個變數mx**
**使mx成為一個極小的數字**
**接下來對每一筆輸入tmp判斷
如果mx小於tmp**
**那就讓mx=tmp**
----
**程式碼如下**
```cpp
int mx = -1, n;
scanf("%d", &n);
for(int i = 0, tmp; i < n; i++){
scanf("%d", &tmp);
if(mx < tmp)
mx = tmp;
}
printf("%d", tmp);
```
----
**反之亦然 如果要取最小值就需要做相反的事**
**至於要怎麼寫就讓讀者自行摸索 應該很[trivial](https://blog.gcos.me/post/2012-09-11_trivial-and-non-trivial/)**
---
<!-- .slide: data-transition="fade" -->
### 程式範例
----
<!-- .slide: data-transition="fade" -->
<h3 class="text-left">
範例1:加總
</h3>
**寫出一個程式輸出$1^4+2^4+...+50^4$的答案**
----
<!-- .slide: data-transition="fade" -->
```cpp
#include <stdio.h>
int main() {
int ans = 0;
for (int i = 0; i <= 50; i++) {
ans += i * i * i * i;
}
printf("%d", ans);
return 0;
}
```
----
<!-- .slide: data-transition="fade" -->
<h3 class="text-left">
範例2:加總
</h3>
**輸入兩數$n$與$m$**
**輸出$1^n+2^n+...+m^n$的答案**
**提示:要用到巢狀迴圈**
<!-- .element: class="fragment" data-fragment-index="1" -->
----
<!-- .slide: data-transition="fade" -->
```cpp
#include <stdio.h>
int main() {
int n, m, ans = 0;
scanf("%d %d", &n, &m);
for (int i = 1; i <= m; i++) {
int tmp = 1;
for (int j = 0; j < n; j++) {
tmp *= i;
}
ans += tmp;
}
printf("%d", ans);
return 0;
}
```
----
<!-- .slide: data-transition="fade" -->
<h3 class="text-left">
範例3:印出三角形
</h3>
<p style="position: relative; right: 100px">
<b>
輸入一個數字n
<br>
輸出兩股為n的等腰直角三角形
</b>
</p>
<img src="https://hackmd.io/_uploads/r1VAdxZ_C.png" style="position: absolute; right: 100px; top: 30px;">
----
<!-- .slide: data-transition="fade" -->
```cpp
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
for (int j = 0; j < i + 1; j++) {
printf("*");
}
printf("\n");
}
return 0;
}
```
---
<!-- .slide: data-transition="fade" -->
### 例題練習
----
<!-- .slide: data-transition="fade" -->
[Zerojudge b971. 等差數列](https://zerojudge.tw/ShowProblem?problemid=b971)
[Zerojudge b970. 我不說髒話 (續)](https://zerojudge.tw/ShowProblem?problemid=b970)
[Zerojudge c418. Bert的三角形 (1)](https://zerojudge.tw/ShowProblem?problemid=c418)
[Zerojudge c418. Bert的三角形 (2)](https://zerojudge.tw/ShowProblem?problemid=c419)
[Zerojudge c420. Bert的三角形 (3)](https://zerojudge.tw/ShowProblem?problemid=c420)
[Zerojudge a244. 新手訓練 ~ for + if](https://zerojudge.tw/ShowProblem?problemid=a244)
[Zerojudge a024. 最大公因數(GCD)](https://zerojudge.tw/ShowProblem?problemid=a024)
[Zerojudge a005. Eva 的回家作業](https://zerojudge.tw/ShowProblem?problemid=a005)
[Zerojudge d581. 三條線](https://zerojudge.tw/ShowProblem?problemid=d581)
----
[Zerojudge d069. 格瑞哥里的煩惱 (t 行版)](https://zerojudge.tw/ShowProblem?problemid=d069)
[Zerojudge d070. 格瑞哥里的煩惱 (0 尾版)](https://zerojudge.tw/ShowProblem?problemid=d070)
[Zerojudge d071. 格瑞哥里的煩惱 (EOF 版)](https://zerojudge.tw/ShowProblem?problemid=d071)
[Zerojudge d649. 數字三角形](https://zerojudge.tw/ShowProblem?problemid=d649)
[Zerojudge a147. Print it all](https://zerojudge.tw/ShowProblem?problemid=a147)
[Zerojudge a263. 日期差幾天](https://zerojudge.tw/ShowProblem?problemid=a263)
[Zerojudge a149. 乘乘樂](https://zerojudge.tw/ShowProblem?problemid=a149)
[Zerojudge d221. 10954 - Add All](https://zerojudge.tw/ShowProblem?problemid=d221)
**要用一點點數學喔**
<!-- .element: class="fragment" data-fragment-index="1" -->
---
<!-- .slide: data-transition="fade" -->
### 以上就是本章節的內容
{"title":"C程式設計導論-for與while迴圈","slideOptions":"{\"title\":\"C程式設計導論-for與while迴圈\",\"author\":\"ShanC\",\"slideOptions\":{\"transition\":\"fade\",\"theme\":\"black\"},\"tag\":\"C程式設計導論\",\"type\":\"slide\"}","description":"認識迴圈結構","contributors":"[{\"id\":\"4f67a8cd-06ae-45dc-a8e3-62c6a41e5a37\",\"add\":9606,\"del\":1365}]"}