//3.C语言特性 //3.1函数的定义 //函数返回类型 函数名(参数){ //dosomthing //}一般的函数定义都是这样的, //有一种古老的函数定义方式,另外起一行对参数进行说明 void printMesg(msg,loopNum) int loopNum; int msg; { int i; for(i = 0;i<loopNum;i++){ printf("第%d次循环%d \n",i+1,msg); } } //3.2函数声明 //函数的声明是用于函数的使用在定义之前 int add(int a,int b); //int main(){ // int maxInt = add(3,8); //} int add(int a,int b){ return a+b; } //3.3参数的传递,Object-C使用的是值传递 void swap(int a,int b){ int temp = a; a = b; b = temp; printf("a的值是%d,b的值是%d",a,b); } //对于指针类型的变量,同样使用的是值传递 /* Draw是一个类 里面有两个属性 int a,int b; void swap(Draw * dw){ int temp = dw.a; dw.a = dw.b; dw.b = temp; } int main (){ Draw dw = [Draw alloc] init]; dw.a = 6; dw.b = 9; return 0; } */ //dw 是一个指针变量,传递的时候也是值传递,复制的也是指针本身, //但是怪就怪在指针操作的是一个Draw对象,不管哪一个指针,操作的 //都是Draw对象。所以属性改变是理所当然了 //3.4递归函数 //3.5内部函数与外部函数 /* 内部函数:定义时使用了static修饰,只能被当前源文件中函数调用,所以称 为内函数 外部函数:定义时使用了extern修饰,或不使用任何修饰符,他可以被任何源 文件调用,这种函数叫外部函数,一般函数都是外部函数。 */ //定义extern函数,省略extern也是允许的 extern printRect(int height,int width){ for(int i=0;i<height;i++){ for(int j=0;j<width;j++){ printf("*");} } } //3.6局部变量与全局变量 //不管什么变量,只要记住变量的范围就是在包含它的{}里面。 //使用extern把变量变成全局变量 extern int globVar; //3.7外部全局变量和内部全局变量 //定义全局变量 int count = 0; //使用外部全局变量 extern int count; //3.8动态存储与静态存储 void fac(n){ auto int a = 1; static int b = 1; a+=n; b+=n; printf("a的值是%d,b的值是%d\n",a,b); } //static可以计算阶乘 /* int fci_2(n){ static int f = 1; f= f*n return f; } for (int i = 1;i<8;i++){ fci_2(8); } */ /*3.9预处理,我个人觉得很重要 1.普通宏 #define PI 3.1415926 2.带参数的宏 #define AREA(r) PI*r*R 直接使用前面的宏来定义新的宏 需要注意的一些问题是 编译器只是简单的替换 比如AREA(10+2)就会出错 3.使用#ifdef #ifndef #else #endif执行条件编译 #define iPad #ifdef iPad printf("iPad"); #else printf("iPhone"); #endif 4.使用#if #elif #else #endif #define AGE 20 #if AGE>23 dosomething #elif AGE>20 doOtherThing #esle doSomeThing #endif */ //3.10结构体 struct 结构体类型名{ //成员列表 } struct rect{ int x; int y; int width; int height; }; struct rect rect1; //每次都要加struct太麻烦 #define RECT struct rect //3.10typedef语句,谨慎使用啊! //一般这两个情况使用能够带来好处 struct point{ int x; int y; }; typedef struct point YLPoint; enum season{spring,summer,fall,winter}; typedef enum season YLSeason; //然后就可以使用它们定义结构体变量和枚举变量了 YLPoint p1; YLSeason s1; //3.11对结构体变量进行初始化 //可以直接对结构体变量进行初始化 //这是正确的 struct rect{ int x; int y; int width; int height; } rect1 = {20,30,100,200}; //这是错误的 rect1 = {12,20,20,90}; struct point{ int x; int y; }; typedef struct point YLPoint; //正确的 YLPoint p1 = {20,10}; //错误的 p1 = {10,10}; //正确的 p1.x = 10; p1.y = 10; //3.12结构体数组 YLPoint points[] = { {12,10}, {13,20}, {34,89} }; //下面的代码是错误的 points[0] = {12,90}; //正确的写法 points[0].x = 20; points[0].y = 30; //3.13块 /* 1.定义块 //定义不带参数,无返回值的块 void (^printString)(void) = ^(void){ NSLog(@"无返回值的块"); }; //定义带参数,有返回值的块,需要注意的是块里面只需要参数类型而不需要写形参 int (^addInt)(int ,int) = ^(int int_a,int int_b){ return int_a+int_b; }; //块可以访问局部变量的值但是不可改变 int myInt = 20; void (^printInt)(void)=^(void){ myInt = 30; NSLog(@"myInt的值是多少%d",myInt); }; myInt = 80; printInt();//打印出来的结果是20 注意:系统在定义块时,会把局部变量的值保存,而不是等到执行时才去访问 所以myInt中值修改后,对块中的myInt没有影响。 如何解决这个问题?使用_block,这样块使用的就是变量本身而非它的值 _block int myInt = 20; void (^printInt)(void)=^(void){ //此处输出80 NSLog(@"myInt的值是多少%d",myInt); myInt = 30; //此处输出30 NSLog(@"myInt的值是多少%d",myInt); }; myInt = 80; printInt(); //此处输出30 NSLog(@"myInt的值是多少%d",myInt); */ //2.复用块变量类型 typedef void (^YLPrintBlock)(int); YLPrintBlock printInt = ^(int num){ printf(num); } YLPrintBlock printSqrt = ^(int num){ printf(num*num); } //3.直接使用Block作为参数 typedef void (^YLProcessBlock)(int); void processArray(int arr[],int lenth,YLProcessBlock process){ for(int i = 0;i <lenth;i++){ process(arr[i]); } } int main (){ int arr[] = {2,3,4}; //传入块作为参数调用processArray processArray(arr,3,^(int num){ NSLog(@"元素的平方是多少%d",num*num); }); //printMesg(3,8); // int a = 6; // int b = 8; // swap(a,b); //printf("a的值是%d,b的值是%d",a,b); int i; for (i=0;i<4;i++){ fac(i); } return 0; }
时间: 2024-11-07 12:45:07