C语言-指针
复杂函数指针
Think in C++中介绍了一种复杂函数指针的分析方法
右左法则:首先从最里面的圆括号看起,然后往右看,再往左看。每当遇到圆括号时,就应该掉转阅读方向。一旦解析完圆括号里面所有的东西,就跳出圆括号。重复这个过程直到整个声明解析完毕。
void (*funcPtr)(); // funcPtr 是一个函数指针,该指针指向的函数没有参数,没有返回值。 void *(*(*fp1)(int))[10]; // fp1 是一个指向函数的指针,该函数拥有一个int型的参数,返回值是一个指向拥有10元素的指针数组,数组中每个元素都是void * 类型。 float (*(*fp2)(int,int,float))(int); // fp2 是一个指向函数的指针,该函数拥有三个参数,分别是int,int和float类型,返回一个指向函数的指针,该函数拥有一个int型的参数,返回值是float类型。 typedef double (*(*(*fp3)())[10])(); // fp3 是一个指向函数的指针,该函数没有参数,返回一个指向拥有十个元素的数组,数组的每个元素是一个函数,这10个函数都没有参数,返回值是double类型。 int (*(*f4())[10])(); // f4是一个函数,返回值是一个指向拥有10个元素的数组,每个数组元素是一个函数指针,这些指针指向的函数返回值为int类型。
1 /** 2 * main函数的参数 3 * main函数可以理解为操作系统调用的函数 4 * 在执行程序的时候可以向main函数传递参数 5 * int main() 6 * int main(int argc) 7 * int main(int argc, char *argv[]) 8 * int main(int argc, char *argv[], char *env[]) 9 * argc - 命令行参数个数 10 * argv – 命令行参数数组 11 * env – 环境变量数组 12 */ 13 14 15 /*普通指针*/ 16 int *p; 17 18 19 /** 20 * 数组指针 21 * 数组指针用于指向一个数组 22 * 数组名是数组首元素的起始地址 , 但并不是数组的起始地址 23 * 通过将取地址符& & 作用于数组名可以得到数组的起始地址 24 * 可通过数组类型定义数组指针 : ArrayType* pointer; 25 * 也可以直接定义 :type (*pointer)[n]; 26 * pointer 为数组指针变量名 27 * type 为指向的数组的类型 28 * n 为指向的数组的大小 29 */ 30 int buf[6]; 31 32 //直接定义: 33 int (*p)[n] = &buf; 34 35 //数组类型重命名定义: 36 typedef int(INT6)[6]; 37 INT6 *p1 = &buf; //数组指针,sizeof(p1) = 6 * sizeof(int) = 24字节 38 INT6 p2; //数组。p2 == int p2[6] 39 40 41 /** 42 * 指针数组 43 * 指针数组是一个普通的数组 44 * 指针数组中每个元素为一个指针 45 * 指针数组的定义 :type* pArray[n]; 46 * type* 为数组中每个元素的类型 47 * pArray 为数组名 48 * n 数组的大小 49 */ 50 int *p[n]; 51 52 53 /** 54 * 函数指针 55 * 函数指针用于指向一个函数 56 * 函数名是执行函数体的入口地址 57 * 可通过函数类型定义函数指针 : FuncType* pointer; 58 * 也可以直接定义 :type (*pointer)(parameter list); 59 * pointer 为函数指针变量名 60 * type 为指向函数的返回值类型 61 * parameter list 为指向函数的参数类型列表 62 */ 63 //直接定义: 64 int (*p)(void); 65 66 //数组类型重命名定义: 67 typedef int(*HSZZ)(void); 68 HSZZ hszz; 69 70 71 /************************************************************ 72 * 等价关系 73 * 74 * 数组参数 等效的指针参数 75 * 一维数组:float a[5] 指针: float *a 76 * 指针数组: int* a[5] 指针的指针:int** a 77 * 二维数组: char a[3][4] 数组的指针:char (*a)[4] 78 *============================================================ 79 * a 和&a 的区别 80 * char a[]={1, 2, 3, 4, 5}; 81 * a为数组是数组首元素的地址 82 * &a为整个数组的地址 83 * a和&a的意义不同其区别在于指针运算 84 *-----------------------------------------------------------*/ 85 a + 1 = (unsigned int)a + sizeof(*a) 86 &a + 1 = (unsigned int)(&a) + sizeof(*&a) = (unsigned int)(&a) + sizeof(a) 87 88 /***************************************************************** 89 * 注意;当指针取变量地址时,指针必须要和变量类型一样,不然会提取到错误(注意:此 90 * 处的错误并不是说里面的数据有错误,而是说提取的数据不是你想要的)数据,如果运气 91 * 好点会直接发生段错误。 92 * 93 * 如果是改变变量的值时,指针类型比变量类型不同,用指针改变变量时,变量的值是未知的; 94 * 运气好的话也会发生段错误,悲催点那就需要自己调试程序,排除错误咯。 95 * 96 * 温馨提醒:除非是特意而为的,否则最好不要这样!!! 97 * 98 * char 型指针 *char 提取1字节数据 99 * short 型指针 *short 提取2字节数据 100 * int 型指针 *int 提取4字节数据 101 * long 型指针(如果是8字节) *long 提取8字节数据 102 * long long 型指针(如果是16字节) *long long 提取16字节数据 103 ******************************************************************/