前言:在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语句,因为这样会增加程序的阅读难度。