前言:在Objective-C中,經常會遇到重復的執行同一段代碼的情況。這時候就會使用到循環功能,和其它編程語言一樣,Objective-C也提供循環結構的語法,包括for循環,while循環和do-while循環。循環的本質就是重復一定的次數來執行某語句,一般應用循環結構基本就是累加或者遍歷對象以便操作。
1.for語句
for循環是開界的,它的一般形式為: for( ; <條件表達式>; ?) 語句; 初始化總是一個賦值語句, 它用來給循環控制變量賦初值; 條件表達式是一個關系表達式, 它決定什么時候退出循環; 增量定義循環控制變量每循環一次后按什么方式變化。這三個部分之間用”;”分開。
例如:for(i=1; i<=10; i++) 語句; 上例中先給i賦初值1, 判斷i是否小于等于10, 若是則執行語句, 之后i的值增加1。再重新判斷, 直到條件為假, 即i>10時, 結束循環。
簡單的for循環
// 打印0~9這10個數字
for(inti=0;i<10;i++){
NSLog(@"%d",i);
}
嵌套的for循環
// 求1!+2!+3!+4!+5!的值
intsum=0;
// 外層循環控制循環次數
for(inti=1;i<6;i++){
intfactorial=1;
// 內層循環求i的階乘
for(intj=1;j<=i;j++){
factorial*=j;
}
sum+=factorial;
NSLog(@"%d! = %d",i,factorial);
}
NSLog(@"1!+2!+3!+4!+5! = %d",sum);
在編寫for循環時可能會遇到在開始循環之前需要初始化多個變量,或者每次循環要計算多個表達式的情況。其實在for循環的任何位置都可以包含多個表達式,只要用逗號分隔這些表達式即可。例如,使用一下形式開始的for循環:
for(inti=0,j=100;i<10;i++,j--)
...
在循環開始之前,將i的值設為0,j的值設為100,每次執行完循環體后,i的值加1,j的值減1。
既然for循環中字段的表達式可以不止一個,那么省略for循環中的一個或多個字段也是可以實現的。省略for語句中某個字段的最常見情形發生在無須計算初始表達式的值時。在這種情況下,for語句的第一個字段可以簡單的保留空白,只要仍然保留分號即可,例如:
for(;j<10;j++)
...
如果省略了for語句的第二個字段,那么這條for語句實際上就是無限循環的,因為循環條件永遠為真,如果需要退出循環就需要執行(return,break或goto語句)。我們也可以使用在for循環中定義循環變量的做法,比如for(int i=0;i<10;i++)的寫法,這個i就是該for循環的局部變量了,離開for循環就無法訪問。
2.while語句
while語句的一般形式為:
while(表達式) ? {語句}
其中表達式是循環條件,語句為循環體。
while語句的語義是:計算表達式的值,當值為真(非0)時, 執行循環體語句。執行完循環體后再次計算表達式的值,如果值為真,再次執行循環體語句,直到表達式的最終求值結果為假時,循環終止。
// 打印0~4這5個數字
inti=0;
while(i<5){
NSLog(@"%d",i);
i++;
}
3.do-while語句
do-while語句的一般形式為:
do {
循環體
} while (表達式)
do-while語句只是while語句的簡單轉置,它把循環條件放在循環的結尾部分,這樣就會先執行循環體中的語句,再判斷條件表達式的真假。
// 打印i的值
inti=3;
do{
NSLog(@"%d",i);
}while(i<2);
上例中循環條件是i < 2,但是i的初始值是3,不滿足循環條件,但是循環體還是被執行了一次,所以說明do-while語句可以確保循環體至少執行一次。
4.for in語句
在OC編程中,遇到遍歷數組的情況時有時會使用到for in循環,筆者剛開始時以為for in只是for循環的一種變體,后來查閱資料才發現for in是一種快速枚舉,所以和for循環是不太一樣的。
// 遍歷數組array
NSMutableArray*array=[NSMutableArrayarrayWithObjects:@"張三",@"李四",@"王五",@"趙六",nil];
for(NSString*stringinarray){
NSLog(@"%@",string);
}
如果在遍歷的過程中對數組容器的內容進行修改的話程序就會崩潰,下面的例子作參考:
// 遍歷數組array
NSMutableArray*array=[NSMutableArrayarrayWithObjects:@"張三",@"李四",@"王五",@"趙六",nil];
for(NSString*stringinarray){
if([stringisEqualToString:@"張三"]){
[array removeObject:string];
}
}
Collection <__NSArrayM: 0x100204b90> was mutated while being enumerated.這個錯誤是說集合在枚舉的過程中發生了突變,執行這樣的操作我們會得到未定義的結果。
快速枚舉的過程中不允許改變容器中的對象,即不允許刪除或者增加枚舉容器中的對象,因為對于一個既定的枚舉器來說,其內部的對象都已經對其進行了枚舉排序,如果你私自添加或者刪除對象,那么其既定的枚舉序列就發生了改變,而這種改變是系統不能識別的,所以OC中不允許這么做。但有時候我們也必須在快速枚舉的過程中刪除一些枚舉容器中的對象,這時候,我們就需要在刪除完一個對象的時候,對其進行break。
5.break語句
在執行循環的過程中,有時候我們會希望在發生特定條件時退出循環(例如檢測到錯誤條件或者在遍歷一系列數據時查找到了需要的記錄)。break語句就可以實現這個目的,只要執行了break語句,程序將立即退出正在執行的循環,循環內的break語句之后的代碼將被跳過,不會被執行,并且該循環的執行也將終止,程序會執行該循環之外的其他內容。
如果在一組嵌套循環中使用break語句,僅僅會退出執行break語句的最內層循環。
break語句的形式是在關鍵字break后面加上一個”;”。形式:break;
6.continue語句
continue語句和break語句類似,但它并不會使循環結束。執行continue語句時,循環會跳過continue語句之后直到循環結束處的所有語句。但是并不會阻止滿足循環條件的循環體的下一次執行。continue語句通常用來根據某個條件繞過循環中的某一組語句。
如果不是必要的情況下,不建議使用break語句或者continue語句,因為這樣會增加程序的閱讀難度。