# 迴圈
## 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或有多筆輸入

直到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: `中和高中`