Ch6 for迴圈

搭配green judge解題系統
Special thanks to 台中女中sagit老師 <(_ _)>

上一章:while迴圈
下一章:雜項:其他資料型態、函式庫、格式化輸出
回目錄:國立科學園區實驗中學C++程式語言自學講義

For迴圈的用途

在上一單元
我們學會了while迴圈

再次複習一次while迴圈的使用時機
1.某段程式要一直重複執行
2.預先不知道要重複幾次,而是藉由判斷某個條件來決定該結束了沒

for迴圈則跟while迴圈非常相似
它的使用時機為
1.某段程式要一直重複執行
2.一開始就已知要重複幾次,所以只要判斷執行幾次了就知道該結束了沒

例如:
印出100個"Hello"
算出某個數字的某次方
算出某個數字的階乘等等

For迴圈的寫法

由於在使用for迴圈時需要計算「迴圈執行幾次了」
所以需要另外使用一個變數來作為「計數器」
通常我們習慣將這個計數器的名稱取作 i 或 j 或 k

而這個計數器主要有三件任務
1.一開始先設定一個起始值
2.設一個檢查條件,每執行一次迴圈就檢查它還符合條件嗎(還符合才能繼續跑迴圈)
3.每執行一次迴圈就將計數器變動一下,例如加一

舉例來說,想要一個迴圈總共執行10次(i從0跑到9)的話

  1. i 的起始值是0
  2. 檢查條件為 i<10 (或i<=9)
  3. 每次迴圈都將i加一

而這三件任務就分別被寫在for迴圈的三個格子裡
像是

int i; //宣告一個計數器 for ( i=0 ; i<10 ; i=i+1 ) //i從0開始;檢查是否還<10;每次加1 { //要重複執行的程式 }

for迴圈的架構如下:
先寫一個for,並且在後面接上一個小括弧()
小括弧內用分號分成3格,分別寫上(計數器=初始值;檢查計數器是否符合條件;改變計數器的值)
接著一個大括號
裡面放入的就是要重複執行的程式

註:i=i+1可以簡化成i++
i=i-1也可以簡化成i--
因為for迴圈實在是太常寫到i=i+1i=i-1
為了方便,以下的範例程式皆會將它寫成i++以及i--

【例題】

輸入一個n,輸出n個"Hello"
例如n為3時,輸出
Hello
Hello
Hello

本題的範例程式如下

int n, i; cin>>n; for(i=0;i<n;i++) //歸零;檢查到n次了沒;每次+1 { cout<<"Hello"<<endl; } cout<<endl; //最後加個換行符號

這樣的程式其實等效於

int n, i; cin>>n; i=0; //歸零 while(i<n) //檢查到n次了沒 { cout<<"Hello"<<endl; i=i+1; //每次+1 } cout<<endl;

for迴圈和while迴圈完全是可以等效轉換的
如果你忘記其中一種怎麼寫,改寫另一種也是可以的
但因為各自有適合的用途
所以還是建議在適合的情況下使用適合的迴圈

【學生練習題】

將計數器的值印出來

當然,計數器本身的值也可以拿來用

【例題】

輸入一個n,輸出從1到n的數字

這題可以寫成

int n, i; cin>>n; for(i=1;i<=n;i++){ cout<<i<<endl; }

計數器不只可以順著數,當然也可以倒著數

【例題】

輸入一個n,輸出從n到1的數字

這題可以寫成

int n, i; cin>>n; for(i=n;i>=1;i--){ cout<<i<<" "; }

【學生練習題】

將計數器的值拿來加減乘除

計數器的值除了可以被印出來
也可以拿來當成運算時的材料
例如每次都把答案加上或乘上目前計數器的值

注意:計數器的值可以拿來當成別的變數運算時的材料
但是最好不要在運算時改動到計數器的值
否則會造成邏輯混亂

【例題】

輸入一個n,輸出1至n的和

我們已經知道和的公式是

n(n+1)2
那麼就來試試看用迴圈算平方和是不是和用公式算的一模一樣

既然要算"和"
可以用一個變數來代表目前的和是多少
每次都將目前的和去加上目前計數器平方的值

int n, i, answer; cin>>n; answer = 0; //和一開始為0 for(i=1;i<=n;i++) { answer = answer+i; //加上計數器的值 } cout<<answer<<endl; //可以檢查是不是跟用公式算的一樣 if(answer == n*(n+1)/2) cout<<"YA!"<<endl;

【例題】

輸入一個n,輸出n的階乘

既然要算階乘
可以先用一個變數來當成目前的積
然後每次都將目前的積乘上目前計數器的值

int n, i, answer; cin>>n; answer = 1; //積一開始為1 (為什麼?) for(i=1;i<=n;i++){ answer = answer*i; } cout<<answer<<endl;

計數器從特定數字開始計

在以上的例子中
我們所用到的計數器,要不就是先歸零,要不就是從1開始
但其實它不管想從幾開始計都是可以的

【例題】

輸入n和m,輸出從n至m的所有整數(包含n與m)

這題可以讓計數器從n開始,到m結束
範例程式如下

int n,m,i; cin>>n; cin>>m; for(i=n;i<=m;i++) //i從n開始;檢查i超過m了沒;i每次都+1 { cout<<i<<endl; }

【例題】

輸入兩個數字a, b
輸出

a(a+1)(a+2)(a+3)...(b2)(b1)b 的值

int a, b, i, ans; cin >> a >> b; ans=1; for(i=a;i<=b;i++){ ans = ans*i; } cout << ans;

【學生練習題】

【例題】

輸入n和m,輸出從n至m的所有整數,兩兩整數間請用"~"來連接
例如n為2,m為5時,即輸出2~3~4~5

這個題目有一個小麻煩
就是每個數字前面都要加上一個飄號~
但唯獨第一個數字前面不能加

這邊提供其中一種解決方法:把第一個數字(n)獨立出來,而迴圈的計數器則從n+1開始

int n, m, i; cin>>n; cin>>m; cout<<n; //先單獨印出第一個數字n for(i=n+1;i<=m;i++) //計數器從n+1開始 { cout<<"~"<<i; //印出飄號跟i }

【學生練習題】

組合技:for與if搭配使用

迴圈裡面還可以再做條件判斷
寫法就和一般的條件判斷相同

【例題】

輸入n,輸出n所有的因數

要判斷一個數字i是否為n的因數,可以判斷n除以i的餘數是否為零,即n%i==0

int n, i; cin>>n; for(i=1;i<=n;i++) { if(n%i==0) cout<<i<<endl; }

【學生練習題】

相同的程式也可以拿來判斷n是不是質數
可以再用一個變數來計算n有幾個因數
如果因數的數量為0,就可以確定n是質數 (1與n除外,因為一定有這兩個因數)

不過i的範圍要注意:
1.i要從2開始,因為1不用檢查
2.i超過根號n時就可以停了 (為什麼?)

不過根號n的寫法有點麻煩(下一章會教到)
因此你可以不要判斷

in
而是改成判斷
iin

int n, i, cnt; cin>>n; cnt=0; for(i=2;i*i<=n;i++) { if(n%i==0) cnt++; } if(cnt>0) cout<<"Not Prime"<<endl; else cout<<"Prime"<<endl;

【學生練習題】

組合技:迴圈裡面還有迴圈

【例題】

輸入n和m,輸出n行的m個飄號
例如n為3,m為5時,輸出
~~~~~
~~~~~
~~~~~

我們已經知道印出一行m個飄號可以這樣寫

for(i=0;i<m;i++) { cout<<"~"; } cout<<endl;

而現在需要將這樣的飄號印出n行來
也就是上面那一段程式要被執行n次才夠
因此可以把上面那一整段程式
再包進一個會被執行n次的迴圈裡

由於i已經被拿去當成剛才的迴圈的計數器了
為了避免衝突
我們要再宣告一個新的計數器:j
因此程式可以寫成

for(j=1;j<=n;j++) { for(i=1;i<=m;i++) { cout<<"~"; } cout<<endl; }

(不過通常i會放在外圈,j會放在內圈,通用習慣問題而已)

請記得,像這樣的「迴圈包迴圈」,並不是一個新的語法概念
就只是單純把一個迴圈寫在另一個迴圈裡而已
寫法規則都沒什麼差別

【學生練習題】

【例題】

輸入n,輸出高和寬為n的等腰直角三角形
例如n為4時,輸出
~
~~
~~~
~~~~

這題可以直接拿上一題的程式來用
唯一不一樣的地方是
內層迴圈的計數器,並非數到n,而是改成數到外層計數器的值

for(j=1;j<=n;j++) { for(i=1;i<=j;i++) //注意,這邊的檢查值改成i<=j囉 { cout<<"~"; } cout<<endl; }

【學生練習題】

補充語法

break

在迴圈內遇到break時,不管怎樣,直接離開迴圈

【例題】

輸入n,輸出大於等於n的第一個5的倍數

(這例子舉得不好,但為了淺顯易懂,還是用這個例子吧)

計數器從n開始數到n+5 (因為這之間一定有5的倍數)
一旦遇到5的倍數並輸出它之後
迴圈就可以直接結束,不用再繼續往下跑了
因此可以使用break

for(i=n;i<=n+5;i++) { if(i%5==0){ cout << i <<endl; break; } }

雖然i不一定有超過n+5
不過一旦它遇到break,還是會直接結束迴圈

continue

在迴圈內遇到continue時,不管怎樣,直接進入下一圈

【例題】

輸入n,輸出1至n之間所有5的倍數

這題你可以使用if來檢查i是否為5的倍數,如果是,則輸出
但你也可以不使用if,而利用continue來控制流程
比方說
在印出i之前,先檢查i是不是5的倍數
如果不是,那就直接continue進入下一輪迴圈

for(i=1;i<=n;i++) { if(i%5!=0) continue; cout<<i<<endl; }

break和continue都不是絕對必要的語法
都可以用其他的寫法來代替
但是在適合的情況下若能善用break和continue
可以讓你寫程式更有效率、有邏輯

上一章:while迴圈
下一章:雜項:其他資料型態、函式庫、格式化輸出
回目錄:國立科學園區實驗中學C++程式語言自學講義