# 迴圈 ## 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: `中和高中`