---
# System prepended metadata

title: 迴圈
tags: [中和高中]

---

# 迴圈

## for()
先舉個例子: 今天我要將一個n=0的變數連續加五次10;

你應該會這樣寫
```c=
#include<stdio.h>
int main(){
    int n=0;
    n+=10;
    n+=10;
    n+=10;
    n+=10;
    n+=10;
    printf("%d",n);
}

```
輸出:
```
50
```

但如果今天需要加100次怎麼辦>_<

所以我們需要用到for迴圈來縮短我們的程式碼。


舉例:

```c=
#include<stdio.h>
int main(){
    int n=0;
    for(int i=0;i<100;i++){
        n+=10;
    }
    printf("%d",n);
}

```
輸出:
```
1000
```

來講一下for迴圈的基礎型態
```c
for( 進迴圈前要執行的陳述句 ; 進入迴圈的條件 ; 每次迴圈結束後執行的陳述句 ){
    陳述句一;
    陳述句二;
    ...
}
```

:::warning
注意: 要記得加`;`
:::

看回上面:
在for迴圈進去之前，我們先宣告了個i的變數，初始化為0，然後判斷是否有達成進入迴圈的條件$(i<100)$，接下來執行陳述句$(n+=10)$，迴圈裡的程式跑完後，執行for迴圈的迴圈結束執行陳述句$(i++)$，再判斷是否達成進入迴圈的條件$(i<100)$

:::info
可能會搞混:
```c
#include<stdio.h>
int main(){
    for(int i=0;i<10;i++){
        printf("%d ",i);
    }
}
```
輸出:
```
0 1 2 3 4 5 6 7 8 9
```

```c
#include<stdio.h>
int main(){
    for(int i=0;i<=10;i++){
        printf("%d ",i);
    }
}
```
輸出:
```
0 1 2 3 4 5 6 7 8 9 10
```

一個執行10次 一個執行11次。
如果你搞混了，記得自己在心理跑跑看。

:::

小提醒:
對於編譯器來說如果直接在for迴圈的(進迴圈前要執行的陳述句)當中宣告變數，那個變數就只能在for迴圈當中使用，跳出迴圈後就會被釋放，如果在跳出迴圈後還要使用那個變數，就會報錯。
```c=
#include<stdio.h>
int main(){
    int n=0,i;
    for(i=0;i<10;i++){
        n++;
    }
    printf("%d",i);
}
```
輸出:
```
10
```


```c=
#include<stdio.h>
int main(){
    int n=0;
    for(int i=0;i<10;i++){
        n++;
    }
    printf("%d",i);
}
```

出錯
```
'i' was not declared in this scope
```
### 帶個例子

[Zero_judge : 新手訓練 ~ for + if](https://zerojudge.tw/ShowProblem?problemid=a244)
題目敘述:

如果 a = 1  請輸出  b+c 

如果 a = 2  請輸出  b-c 

如果 a = 3  請輸出  b*c 

如果 a = 4  請輸出  b/c 

結果請用整数輸出 


解法:
```c=
#include<stdio.h>
int main(){
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        long long int a,b,c;
        scanf("%lld%lld%lld",&a,&b,&c);
        if(a==1){
            printf("%lld\n",b+c);
        }else if(a==2){
            printf("%lld\n",b-c);
        }else if(a==3){
            printf("%lld\n",b*c);
        }else{
            printf("%lld\n",b/c);
        }
    }
}

```

---

### 雙層迴圈?

```c=
for( 進迴圈前要執行的陳述句 ; 進入迴圈的條件 ; 每次迴圈結束後執行的陳述句 ){
    for( 進迴圈前要執行的陳述句 ; 進入迴圈的條件 ; 每次迴圈結束後執行的陳述句 ){
        陳述句一;
        陳述句二;
        ...
    }
}
```
直接舉例
```c=
#include<stdio.h>
int main(){
    for(int i=0;i<5;i++){
        printf("%d ",i);
        for(int j=0;j<10;j++){
            printf("%d ",j);
        }
        printf("\n");
    }
}
```
輸出
```
0 0 1 2 3 4 5 6 7 8 9
1 0 1 2 3 4 5 6 7 8 9
2 0 1 2 3 4 5 6 7 8 9
3 0 1 2 3 4 5 6 7 8 9
4 0 1 2 3 4 5 6 7 8 9
```

還可以加上很多迴圈，但最常用的就雙層和單層而已。

### 帶個例子

[ZeroJudge - c418: Bert的三角形 (1)](https://zerojudge.tw/ShowProblem?problemid=c418)

題目敘述:

Bert 想要一個 n 層的三角形，第 i 層就要有 i 個 " * "

請你寫個程式幫幫可憐的 Bert ~~

輸入:
3

輸出:
*
**
\***

解答:

```c=
#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");
    }
}
```


---

## while
```c=
while(條件句){
    陳述句
}
```
只要符合while的條件句，就會一直執行while迴圈裡的程式。

舉例:
```c=
#include <stdio.h>
int main(){
    int n=10;
    while(n>0){
        printf("%d\n",n);
        n--;
    }
}
```
輸出:
```
10
9
8
7
6
5
4
3
2
1
```

---

## do while
```c=
do{
    陳述句
}while(條件句);
```
do while迴圈會先做一次陳述句的程式再判斷是否符合條件

舉例:
```c=
#include <stdio.h>
int main(){
    int n=10;
    do{
        printf("%d\n",n);
        n--;
    }while(n>0);
}
```
輸出:
```
10
9
8
7
6
5
4
3
2
1
```

## EOF
我們可以常常在Zerojudge上看到輸入直到EOF或有多筆輸入
![](https://i.imgur.com/uzZZnbe.jpg)
直到EOF是什麼意思
EOF其實就是代表-1

```c=
while(scanf("%d",&n) != EOF){ 
	
}
```
scanf("%d%d", &a, &b); 如果a和b都被成功讀入，那麼scanf的返回值就是2；
如果只有a被成功讀入，返回值為1
如果a和b都未被成功讀入，返回值為0
如果遇到錯誤或遇到end of file，返回值為EOF，
while的意思就是說當前緩衝區還有東西時就一直讀取，直到輸入緩衝區中的内容為空的時候停止。

Windows中，Ctrl-Z表示EOF。 


___

### 看一下EOF的例子

[Zero_judge 文文的求婚](https://zerojudge.tw/ShowProblem?problemid=a004)

題目敘述:
文文為即將出國的珊珊送行，由於珊珊不喜歡別人給文文的那個綽號，意思就是嘲笑文文不夠 聰明，但珊珊沒把握那個綽號是不是事實，所以珊珊決定考驗文文，於是告訴文文說，如果你能在 我回國之前回答我生日那年是不是閏年，則等她回國後就答應他的求婚。文文抓抓腦袋想不出來， 於是決定讓最擅長做運算的電腦來幫忙。

解法:
西元年份除以4不可整除，為平年。
西元年份除以4可整除，且除以100不可整除，為閏年。
西元年份除以100可整除，且除以400不可整除，為平年
西元年份除以400可整除，為閏年
```c
#include<stdio.h>
#include<stdlib.h>
int main(){
    int y;
    while(scanf("%d",&y)!= EOF){
        if((y%400==0) || (y%100!=0 && y%4==0)){
            printf("閏年\n");
        }
        else{
            printf("平年\n");

        }
    }
    return  0;
}
```


---
## continue、break

`continue`代表無視接下來的程式，回到迴圈的開頭
`break`代表直接跳出迴圈

continue舉例:
```c=
#include<stdio.h>
int main(){
    for(int i=0;i<5;i++){
        if(i%2>0)continue;
        else printf("%d ", i);
    }
}
```
輸出:
```
0 2 4
```

break舉例:
```c=
for(int i=0;i<5;i++){
    if(i==3) break;
    printf("%d", i);
}
```

輸出:
```
0 1 2
```




---
### for和while小知識

for迴圈的()裡至少要有兩個`;`

`for(;;)`和`while(1)` 是無窮迴圈。

```c
for(int i=0;i<n;i++){
     陳述句;   
}
```
可以寫成
```c
int i=0;
while(i<n){
    i++;    
}
```

while 迴圈常用時機 : 當你不知道要做多少次才能達成題目的目標，透過continue 和 break 的配合，產生出你要的答案。

for迴圈 : 很常用 恩...。


## 來個練習題
[一種奇怪的演算法](https://chiscoj.com/problem/a012) ----<while迴圈練習>
[懸崖](https://chiscoj.com/problem/a013)  ------------------<雙層迴圈練習>
[醒來的時間](https://chiscoj.com/problem/a014) -----------<EOF練習>
[狂熱粉絲](https://chiscoj.com/problem/a015) --------------<for迴圈練習>

###### tags: `中和高中`