Objective C流程控制、数据结构 Objective C中的运算符 Objective C分类(Category)和协议(Protocol) Objective C流程控制、数据结构 内容概述 选择 if else switch 三元运算 循环for while do while break continue 常用数据结构数组、栈 7.1 选择 if else switch 三元运算 选择又称条件,即根据条件来更改程序的执行流程,如果条件成立执行A语句,否则执行B语句。条件语句一般有三种格式即if、if else、if else if else。格式如下: if (布尔表达式){ 语句或块; } if (条件为真) { 语句或块; }else if { 语句或块; }else { 语句或块; } 下面通过一个案例来演示,条件语句的用法。使用arc4random函数随机生成0到100之间的随机数,使用条件语句判断两个数字的大小,并输出结果。 void test1(){ // 使用arc4random函数随机生成0到100之间的随机数 int i = arc4random()%100; int j = arc4random()%100; // 输出当前随机数 NSLog(@"i=%d",i); NSLog(@"j=%d",j); // 判断大小 if (i>j) { NSLog(@"i>j"); }else if(i==j){ NSLog(@"i==j"); }else{ NSLog(@"i<j"); } } 和所有其他编程语言一样,Objective C中也有程序的流程控制,包括顺序执行、选择和循环。本节我们讲述Objective C中的循环。Objective C中的循环基本和c语言的循环相同,唯一的差别是多了一个增强for循环。 如果判断条件比较多,if else 结构很繁琐,这样可以使用另外一种判断结构它是switch结构条件判断。switch的结构如下所示。 switch (表达式0){ case 表达式1: 语句; break; case 表达式2: 语句; break; default: 语句; break; } 该结构条件判断中表达式1、表达式2和表达式0比较,如果其中之一匹配则执行相应语句,这里注意表达式1和表达式2不能重复。程序遇见break语句即刻退出。注意如果没有break语句程序将继续执行。下面通过一个案例来演示switch语句的用法,这里是模拟一个游戏精灵随机运动方向。 #define UP 1 #define DOWN 2 #define LEFT 3 #define RIGHT 4 void test2(){ // 随机生产1到4之间的方向值 int direction = arc4random()%4+1; // 输出当前方向 NSLog(@"direction=%d",direction); // 通过switch判断当前方向 switch (direction) { case UP: NSLog(@"Move UP"); break; case DOWN: NSLog(@"Move DOWN"); break; case LEFT: NSLog(@"Move LEFT"); break; case RIGHT: NSLog(@"Move RIGHT"); break; default: NSLog(@"ERROR..."); break; } } 除了,if else和switch结构的条件判断,还有一个简洁的条件判断结构,它被称为三元运算,结构如下:关系表达式 ? 表达式1 : 表达式2。下面通过比较两个数和三个数的大小来演示三元运算的用法。 void test3(){ // 声明两个整数 int a = 1,b = 2; // 使用三元运算判断两个数的大小 int max = a>b?a:b; // 输出比较结果 NSLog(@"a=%d,b=%d,max=%d",a,b,max); // 声明三个数字 int x = 50,y = 70,z = 30; // 通过嵌套三元运算比较三个数的大小 max = x>y?(x>z?x:z):(y>z?y:z); // 输出比较结果 NSLog(@"x=%d,y=%d,z=%d,max=%d",x,y,z,max); } 7.2 循环for while do while break continue 所谓循环就是重复多次执行某件事情,Objective C中提供的循环包括for循环、while循环、do while循环和增强型for循环。 如果明确知道循环的次数使用for循环,如果并不清楚循环的次数一般使用while循环和do while循环。do while循环至少执行一次,而while循环有可能一次都不执行。增强型for循环一般用在不需要使用索引的集合对象当中,例如,数组、字典等。 for循环,for循环的结构如下: for (初始条件; 布尔表达式; 改变表达式){ 语句块 } 首先声明初始条件值,初始条件只执行一次,然后重复计算布尔表达式和改变条件的值,如果布尔表达式的结果为假,则退出循环。下面的循环计算1到10的求和。 void test1(){ // 定义求和结果 int sum = 0; // 从1开始循环10次 for (int i=1; i<=10; i++) { // 累加结果 sum+=i; } NSLog(@"sum=%d",sum); } 复杂的循环可以嵌套若干层,这里使用一个两层循环嵌套来打印一个乘法口诀表。 void test2(){ // 循环1到9 for (int i=1; i<=9; i++) { // 根据外层循环来循环 for (int j=1; j<=i; j++) { // 打印输出 printf("%d*%d=%d ",j,i,i*j); } // 换行 printf("\n"); } } 还可以使用增强型for循环来遍历一些不需要使用索引的集合对象。例如,数组、字典等数据结构。 下面代码使用增强型for循环遍历数组中的元素。 void test3(){ // 定义数组 NSArray *array = @[@"Java",@"c++",@"c#",@"php"]; // 增强型for循环 for(NSString *item in array){ // 输出 NSLog(@"item=%@",item); } } 如果循环的次数并不明确我们可以使用while循环和do while循环。下面是while循环和do while循环的结构。 while (布尔表达式) { 语句或块 } do{ 语句或块; }while (布尔测试) 下面两个程序,第一个使用while实现了1到10的累加,另外一个使用do while循环每个一秒输出一个递增数字。 void test5(){ // 每隔1秒输出 int i = 1; while (i<10) { NSLog(@"i=%d",i++); [NSThread sleepForTimeInterval:1]; } } void test4(){ // 求和结果 int sum = 0; // 计数值 int i = 1; // 循环条件 while (i<=10) { // 累加 sum = sum+i; // 循环条件自增 i++; } NSLog(@"sum=%d",sum); } 在循环结构中,我们经常会根据某些条件,结束某次循环或退出整个循环。这样可以使用break和continue来实现。continue是结束本次循环进行下一次循环,break是退出整个循环。 下面的代码演示了当i为4或7时,退出本次循环,进行下一次循环。 // 使用continue void test6(){ for(int i=1;i<=10;i++){ if(i==4 || i==7){ continue; } NSLog(@"i=%d",i); } } 另外一个是当变量i为5时退出整个循环。 // 使用break void test7(){ for(int i=1; i<=10; i++){ if(i==5)break; NSLog(@"i=%d",i); } } 7.3 常用数据结构数组、栈 和c语言相似我们可以在Objective C中使用常见的数组、栈、队列、链表、树等数据结构。本书不是专门讲解数据结构的书籍,所有这里讲解两种常用的数据结构数组和栈。 对数据结构的操作和数据库类似,可以实现数据的增加、删除、修改和查询等操作。 下面演示数组数据结构的操作。首先定义数组的大小,根据大小声明数组,并为数组赋值,这个过程也可以叫做添加。 // 数组大小 int size = 10; // 索引 int i; // 声明数组 int array[size]; // 给数组赋值; array[0]=10; array[1]=8; array[2]=9; array[3]=6; array[4]=7; array[5]=4; array[6]=3; array[7]=1; array[8]=2; array[9]=5; // 显示数组中的元素 for (i=0; i<size; i++) { printf("%d ", array[i]); } printf("\n"); 下面是搜索功能,根据给定的key来循环搜索该值,如果找到显示,如果未找到提示未找到。 // 要搜索的key int searchKey =5; //是否搜索到了 BOOL isSearch = NO; // 循环判断 for (i=0; i<size; i++) { // 如果找到 if (array[i]==searchKey) { // 显示索引 printf("%d at index %d",searchKey,i); isSearch = YES; break; } } if (!isSearch) { printf("not found!"); } 删除,删除的基本思路是首先查找到该元素,然后从该元素的索引位置向前覆盖其他元素,最后数组大小减1,这样达到删除效果。 int deleteItem = 6; for (i=0; i<size; i++) { if (array[i]==deleteItem) { break; } } for (int k = i; k<size; k++) { //向前覆盖 array[k]=array[k+1]; } // 大小减1 size--; // 显示 for (i = 0; i<size; i++) { printf("%d ",array[i]); } 修改,修改的基本思路还是查找到该对象,然后重新给该元素赋值,达到修改目的。 // 要修改的元素 int searchItem = 6; // 将修改成100 int updatedItem = 100; // 修改前 printf("before:"); displayArray(array,size); // 查找并修改 for (i=0; i<size; i++) { if (array[i]==searchItem) { array[i]=updatedItem; break; } } // 修改后 printf("after:"); displayArray(array,size); 除了数组,另外一个常用的数据结构上是栈stack,栈这种数据结构的特点是,后进先出(Last in first out)LIFO。下面我们定义一个栈结构,并给其中的数据进行维护。 int stackSize=5; int stackArray[]; int stackTop=-1; // 入栈/压栈 void push(int a){ if (stackTop<stackSize-1) { stackArray[++stackTop]=a; }else{ printf("stack full.\n"); } } // 出栈 int pop(){ int temp = stackArray[stackTop--]; stackArray[stackTop]=0; return temp; } // 取栈顶元素 int peek(){ return stackArray[stackTop]; } // 是否为空 bool isEmpty(){ return (stackTop==-1); } // 是否为满 bool isFull(){ return (stackTop==stackSize-1) ; } Objective C中的运算符 Objective C分类(Category)和协议(Protocol)