2017年1月5日 星期四

Ch05 - 介紹 Objective-C 迴圈

Objective-C 程式設計學習筆記 Ch05

  • Ch05-介紹 Objective-C 迴圈。
  • 本章會介紹 for, while 以及 do 這三種迴圈的程式敘述。
  • 介紹關係運算子 ( 如 >=, ==...), 介紹遞增,遞減運算子。
迴圈可以幫助我們以一些確定的規則,進行重複的程式碼,以利達到我們所預期的效果。這是一個蠻常用到的技巧。只要你能描述規則,迴圈可以幫你省下很多程式碼。以下會儘量用淺顯易懂的舉例,讓你體會迴圈的方便之處。

目錄:

  • (1) for 敘述
  • (2) while 敘述
  • (3) do...while 敘述
  • (4) break
  • (5) continue

(1) for 敘述

假如我們想要計算 1 + 2 + 3 + 4 + 5 的總和,你會怎麼做呢? 比較方便的方法是直接使用 NSLog 並把算式寫在參數中 :
NSLog(@"1 + 2 + 3 + 4 + 5 = %i", 1+2+3+4+5); 
如願,我們真的會得到正確的結果,也就是 15。
但是,假如今天是 1 加到 100 呢? 雖然我們真的有辦法手動用鍵盤輸入 1~100 的相加,但是這並不是長久之計,假如今天變成了要計算讓使用者輸入起始值到 100 的總和,我們就無法預測使用者想要從多少開始,這時候我們來看看如何使用 for 敘述,做到從 1 加到 100,並且把最後的總和印出。
我們先來看一下 for 敘述的規則:
for(運算初始式; 條件式; 更新運算式){
  程式碼敘述
}
假如你的程式碼敘述只有一行,你可以省略大括號:
for(運算初始式; 條件式; 更新運算式)
  程式碼敘述
接著我們來看看如何做到 1~100 的總和:
int total;
for(int a = 1 ; a<=100 ; a=a+1){
   total = total + a;
}
NSLog(@"1+2+3+..100 = %i", total);
實作結果:
2013-12-29 ~[19854:303] 1+2+3+..100 = 5050
我們來看看這段 for 迴圈如何做到 1~100 累加的結果,首先我們宣告一了 total 變數,型別是 int,接著開始一段 for 迴圈的敘述,我們在運算初始式宣告一個變數 a ,a 的初始值是 1,接著我們在 for 迴圈的條件式設定這個迴圈的條件式 a<=100,也就是說,當 a<= 100 這個條件成立的時候,才會執行 for 迴圈裡面的程式碼,接著是更新運算式,每一次迴圈執行時都把 a 的值加 1,注意!更新運算式是當每次 for 迴圈執行完才會執行。
而 total 的值會在迴圈每執行一次的時候更新,因此只要迴圈執行條件 (當 a<=100 ) 成立,都會更新 total 的值 total = total + a;,你可以透過在 for 迴圈的程式敘述 NSLog 出 a 的值,觀察 a 值的變化:
NSLog(@"1 + 2 + 3 + 4 + 5 = %i", 1+2+3+4+5);
int total;
for(int a = 1 ; a<=100 ; a=a+1){
   total = total + a;
   NSLog(@"a =  %i", a);        
}
NSLog(@"1+2+3+..100 = %i", total);

區域變數的概念

在上面的例子,我們在 for 迴圈的初始運算式才宣告 for(int a=1;...) 由於我們是在 for 迴圈的敘述裡面才宣告這個變數,因此只有 for 迴圈裡面才存取的到 a 這個變數的值,因此 a 變數是一個區域變數,只有在宣告變數 a 的區域才有辦法存取。
你也可以把變數 a 的宣告放到外面使之變成全域變數 (任何地方都可以存取),也不會影響程式執行:
int a, total;
for( a = 1 ; a<=100 ; a=a+1){
   total = total + a;
}
NSLog(@"1+2+3+..100 = %i", total);
不過由於變數 a 在這個例子中除了 for 迴圈之外沒有其他地方需要用到,因此建議將變數 a 的宣告放在 for 迴圈的初始運算式,讓它成為區域變數使用即可。

比較運算子

我們在條件式設定 a<=100,<= 是一種條件運算子(也有書本寫關係運算子),比較運算子用來比較兩個運算的結果是否為 TRUE 或 FALSE,其運算的結果會是布林值,常見的比較算子如下:
運算子名稱範例
==等於a == b
!=不等於3!= 4
<小於4 < 5
<-小於等於4 <= 5
>大於a > b
>=大於等於a >= b
比較運算子常常出現在需要條件判斷的地方,我們在下一章節的流程 (條件) 控制會經常使用到。

遞增,遞減運算子

我們在 for 迴圈的更新運算式寫道 a=a+1,意思是每次迴圈執行完後,a 的值遞增 1,而這種每次加 1 或是每次減 1 ,有一種運算子可以表達,那就是遞增,遞減運算子。
a = a+1 也可以表示成 a++
a = a-1 也可以表示成 a--
這只是一種表達方式,可能一開始會不太習慣,但是使用久了會發現它很方便。
來個遞減運算子的範例:
int a;
for( a = 100 ; a>=1 ; a--){
   NSLog(@"a is %i", a);
}
執行這個範例,我們把 a 的初始值設定為 100 , 只要 a 滿足 a>=1 這個條件時,將會執行裡面的程式碼,接著 a-- ,將 a 的值地減 1 ,一直不斷的重複直到 a 不滿足 a>=1 這個條件時。
你看看 NSLog 的 a 值是否從 100 遞減至 1 。
舉例一些常見的運算式: (以下表格代表左邊的運算是相當於右邊的運算式)
運算式基本運算式
a++a = a + 1
a--a = a - 1
a += ba = a + b
a -= ba = a - b
a*=a = a * b
a/=a = a / b
a%=a = a % b

一個以上的運算初始值

for 迴圈的運算初始值,可以讓你定義一個以上的運算初始值,但多的運算是必須使用 ,隔開。
以下的範例是,同時有兩個初始值,分別是 a 跟 b (用,隔開),當 a <= 100 時, 更新運算子為 a 遞增 1,而 b 遞減 1 (一樣用,隔開):
int a,b;
for( a = 1, b=50 ; a<=100 ; a++, b--){
   //your code
}

for 迴圈可以巢狀

所謂巢狀就是一個 for 迴圈裡面還可以在包另一個 for 迴圈。
for( 運算初始式; 條件式; 更新運算式 ){
 //your code
 for( 運算初始式; 條件式; 更新運算式 ){
   //your code       
 }
}

(2) while 敘述

while 的敘述為:
while (條件式){
 程式碼;
}
比起 for 的敘述, while 可能相對單純一點。while 的敘述若以中文的說法,就是當條件成立,就執行裡面的程式碼,比方說當 a <=5 時,印出 a 的值:
int a = 1;
while(a<=5){
   NSLog(@"a's value: %i", a);
   a++;
}
執行結果:
a's value: 1
a's value: 2
a's value: 3
a's value: 4
a's value: 5
需要注意的是一定要在 while 的程式碼加上 a++; 讓 a 每次遞增 1,這樣第五次進到 while 程式時,a 就會等於 6,於是才會停止繼續執行 while 的程式碼了,若少加了這行,則會變成無窮迴圈,因為 a 的值沒有改變,永遠等於 1,而且也永遠符合 while 的條件式 (a<=5),使用 while 的話一定要注意這一點,別讓它成為無窮迴圈。

(3) do...while 敘述

do...while 的敘述如下:
do {
  程式碼
} while (條件式);
do...while 敘述跟 while 很類似,其實就是把順序倒過來而已,使用 while 的時候,會先判斷是不是符合條件式在執行程式碼,而 do...while 是先執行程式碼,在判斷 while 裡面的條件式是不是成立。
我們用 do...while 做一個 1 累加到 10 的結果:
int a = 1;
int total = 0;        
do{
   total += a++;
  }while (a<=10);
NSLog(@"1+2+3...+10 =  %i", total);
執行結果:
1+2+3...+10 =  55

(4) break 敘述

break 用在當某個條件成立時,離開迴圈的執行。以下範例是 a=1, a<=10,a 每次遞增 1,但是 for 迴圈裡面多一個條件判斷 (if 敘述在下章介紹),我們利用 if 條件式,判斷當 a 等於 5 時,就使用 break 離開迴圈。
int a = 1;
int total = 0;
for( a = 1 ; a <= 10 ; a++){
   total +=a;
   NSLog(@"a is %i", a);
   NSLog(@"total is %i", total);
   //當 a 等於 5 時,即中斷 for 迴圈
   if(a==5){
      break;
   }
}
執行結果:
2013-12-30 ~[20695:303] a is 1
2013-12-30 ~[20695:303] total is 1
2013-12-30 ~[20695:303] a is 2
2013-12-30 ~[20695:303] total is 3
2013-12-30 ~[20695:303] a is 3
2013-12-30 ~[20695:303] total is 6
2013-12-30 ~[20695:303] a is 4
2013-12-30 ~[20695:303] total is 10
2013-12-30 ~[20695:303] a is 5
2013-12-30 ~[20695:303] total is 15
當 a 等於 5 時,就沒有在執行 for 裡面的程式了,因為已經被 break 了。 下個章節會在詳加介紹 break 敘述。

(5) continue 敘述

continue 的作用是立即跳出,不會再執行下面的程式碼,回到迴圈開頭重新執行。
下方的範例,a每次遞增 1,而條件是 a <= 5 時才會執行,我們利用 continue 的特性跟 if 敘述,故意跳開當 a=2 以及 a=4 時不要往下執行 NSLog 函式。最後只會印出 1, 3, 5 這三種 a 的值。
int a = 1;

for( a = 1 ; a <= 5 ; a++){
  if(a==2 || a==4){
    continue;
  }
  NSLog(@"a is %i", a);
}
執行結果:
2013-12-30 ~[20736:303] a is 1
2013-12-30 ~[20736:303] a is 3
2013-12-30 ~[20736:303] a is 5

下一章節,將會介紹 Objective-C 流程控制 。

0 意見:

張貼留言