前言:在Objective-C中闷盔,經(jīng)常會遇到重復(fù)的執(zhí)行同一段代碼的情況始花。這時候就會使用到循環(huán)功能消约,和其它編程語言一樣,Objective-C也提供循環(huán)結(jié)構(gòu)的語法氢伟,包括for循環(huán)榜轿,while循環(huán)和do-while循環(huán)。循環(huán)的本質(zhì)就是重復(fù)一定的次數(shù)來執(zhí)行某語句朵锣,一般應(yīng)用循環(huán)結(jié)構(gòu)基本就是累加或者遍歷對象以便操作谬盐。
1.for語句
for循環(huán)是開界的,它的一般形式為: for( ; <條件表達式>; ?) 語句诚些; 初始化總是一個賦值語句, 它用來給循環(huán)控制變量賦初值飞傀; 條件表達式是一個關(guān)系表達式, 它決定什么時候退出循環(huán); 增量定義循環(huán)控制變量每循環(huán)一次后按什么方式變化诬烹。這三個部分之間用”;”分開砸烦。
例如:for(i=1; i<=10; i++) 語句; 上例中先給i賦初值1, 判斷i是否小于等于10, 若是則執(zhí)行語句, 之后i的值增加1。再重新判斷, 直到條件為假, 即i>10時, 結(jié)束循環(huán)绞吁。
簡單的for循環(huán)
// 打印0~9這10個數(shù)字
for(inti=0;i<10;i++){
NSLog(@"%d",i);
}
嵌套的for循環(huán)
// 求1!+2!+3!+4!+5!的值
intsum=0;
// 外層循環(huán)控制循環(huán)次數(shù)
for(inti=1;i<6;i++){
intfactorial=1;
// 內(nèi)層循環(huán)求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循環(huán)時可能會遇到在開始循環(huán)之前需要初始化多個變量幢痘,或者每次循環(huán)要計算多個表達式的情況。其實在for循環(huán)的任何位置都可以包含多個表達式掀泳,只要用逗號分隔這些表達式即可雪隧。例如,使用一下形式開始的for循環(huán):
for(inti=0,j=100;i<10;i++,j--)
...
在循環(huán)開始之前员舵,將i的值設(shè)為0脑沿,j的值設(shè)為100,每次執(zhí)行完循環(huán)體后马僻,i的值加1庄拇,j的值減1。
既然for循環(huán)中字段的表達式可以不止一個,那么省略for循環(huán)中的一個或多個字段也是可以實現(xiàn)的措近。省略for語句中某個字段的最常見情形發(fā)生在無須計算初始表達式的值時溶弟。在這種情況下,for語句的第一個字段可以簡單的保留空白瞭郑,只要仍然保留分號即可辜御,例如:
for(;j<10;j++)
...
如果省略了for語句的第二個字段,那么這條for語句實際上就是無限循環(huán)的屈张,因為循環(huán)條件永遠為真擒权,如果需要退出循環(huán)就需要執(zhí)行(return,break或goto語句)阁谆。我們也可以使用在for循環(huán)中定義循環(huán)變量的做法碳抄,比如for(int i=0;i<10;i++)的寫法,這個i就是該for循環(huán)的局部變量了场绿,離開for循環(huán)就無法訪問剖效。
2.while語句
while語句的一般形式為:
while(表達式) ? {語句}
其中表達式是循環(huán)條件,語句為循環(huán)體焰盗。
while語句的語義是:計算表達式的值璧尸,當(dāng)值為真(非0)時, 執(zhí)行循環(huán)體語句姨谷。執(zhí)行完循環(huán)體后再次計算表達式的值逗宁,如果值為真映九,再次執(zhí)行循環(huán)體語句梦湘,直到表達式的最終求值結(jié)果為假時,循環(huán)終止件甥。
// 打印0~4這5個數(shù)字
inti=0;
while(i<5){
NSLog(@"%d",i);
i++;
}
3.do-while語句
do-while語句的一般形式為:
do {
循環(huán)體
} while (表達式)
do-while語句只是while語句的簡單轉(zhuǎn)置捌议,它把循環(huán)條件放在循環(huán)的結(jié)尾部分,這樣就會先執(zhí)行循環(huán)體中的語句引有,再判斷條件表達式的真假瓣颅。
// 打印i的值
inti=3;
do{
NSLog(@"%d",i);
}while(i<2);
上例中循環(huán)條件是i < 2,但是i的初始值是3,不滿足循環(huán)條件譬正,但是循環(huán)體還是被執(zhí)行了一次宫补,所以說明do-while語句可以確保循環(huán)體至少執(zhí)行一次。
4.for in語句
在OC編程中曾我,遇到遍歷數(shù)組的情況時有時會使用到for in循環(huán)粉怕,筆者剛開始時以為for in只是for循環(huán)的一種變體,后來查閱資料才發(fā)現(xiàn)for in是一種快速枚舉抒巢,所以和for循環(huán)是不太一樣的贫贝。
// 遍歷數(shù)組array
NSMutableArray*array=[NSMutableArrayarrayWithObjects:@"張三",@"李四",@"王五",@"趙六",nil];
for(NSString*stringinarray){
NSLog(@"%@",string);
}
如果在遍歷的過程中對數(shù)組容器的內(nèi)容進行修改的話程序就會崩潰,下面的例子作參考:
// 遍歷數(shù)組array
NSMutableArray*array=[NSMutableArrayarrayWithObjects:@"張三",@"李四",@"王五",@"趙六",nil];
for(NSString*stringinarray){
if([stringisEqualToString:@"張三"]){
[array removeObject:string];
}
}
Collection <__NSArrayM: 0x100204b90> was mutated while being enumerated.這個錯誤是說集合在枚舉的過程中發(fā)生了突變,執(zhí)行這樣的操作我們會得到未定義的結(jié)果稚晚。
快速枚舉的過程中不允許改變?nèi)萜髦械膶ο蟪缍拢床辉试S刪除或者增加枚舉容器中的對象,因為對于一個既定的枚舉器來說客燕,其內(nèi)部的對象都已經(jīng)對其進行了枚舉排序鸳劳,如果你私自添加或者刪除對象,那么其既定的枚舉序列就發(fā)生了改變也搓,而這種改變是系統(tǒng)不能識別的棍辕,所以O(shè)C中不允許這么做。但有時候我們也必須在快速枚舉的過程中刪除一些枚舉容器中的對象还绘,這時候楚昭,我們就需要在刪除完一個對象的時候,對其進行break拍顷。
5.break語句
在執(zhí)行循環(huán)的過程中抚太,有時候我們會希望在發(fā)生特定條件時退出循環(huán)(例如檢測到錯誤條件或者在遍歷一系列數(shù)據(jù)時查找到了需要的記錄)。break語句就可以實現(xiàn)這個目的昔案,只要執(zhí)行了break語句尿贫,程序?qū)⒘⒓赐顺稣趫?zhí)行的循環(huán),循環(huán)內(nèi)的break語句之后的代碼將被跳過踏揣,不會被執(zhí)行庆亡,并且該循環(huán)的執(zhí)行也將終止,程序會執(zhí)行該循環(huán)之外的其他內(nèi)容捞稿。
如果在一組嵌套循環(huán)中使用break語句又谋,僅僅會退出執(zhí)行break語句的最內(nèi)層循環(huán)。
break語句的形式是在關(guān)鍵字break后面加上一個”;”娱局。形式:break;
6.continue語句
continue語句和break語句類似彰亥,但它并不會使循環(huán)結(jié)束。執(zhí)行continue語句時衰齐,循環(huán)會跳過continue語句之后直到循環(huán)結(jié)束處的所有語句任斋。但是并不會阻止?jié)M足循環(huán)條件的循環(huán)體的下一次執(zhí)行。continue語句通常用來根據(jù)某個條件繞過循環(huán)中的某一組語句耻涛。
如果不是必要的情況下废酷,不建議使用break語句或者continue語句,因為這樣會增加程序的閱讀難度抹缕。