今天看了一个博友的帖子,是关于复杂类型声明的;于是便一起复习了一下; 做了个总结;个人感觉这个方法能够分析任何复杂类型的声明; 复杂类型的声明主要涉及各种类型的指针,如果没有指针那么估计就没有什么 复杂的类型了.由于本人水平有限,还请各位大虾多多指教. 首先看以下最基本的==============================================> 1.看一个变量是否是指针: 如果变量左边紧跟*;并且用括号和变量相结合, 那边它是指针;否则它不是;例如: (int*)array[10] array是指针数组,不是指针; int (*array)[10] array是数组指针. --------------------------------------------------------------------------- (int *)fun() fun 是函数 int (*fun)() fun 是函数指针 ------------------------------------------------------------------------ int *a a是指针; (int *)a a 的类型未知,这里把a强制转换成指针 实际上指针数组,数组指针都表示一个地址,可以把数组名赋值给数组指针; 他们区别在于,数组名地址固定,而数组指针则可以指向任何同类型的数组; 函数指针和函数名也有类似关系;函数指针可以随便指,函数名却是一个固定地址. 2.形式上区别: (TYPE)(*array)[SIZE]---------------------------->A array是一个数组指针,指向数组(TYPE)ArrayName[SIZE]
(TYPE)array[SIZE] ---------------------------->B array是一个数组 ---------------------------------------------------------------------------------- (RET TYPE)(*fun)(PARAM)------------------------->C fun是函数指针,指向函数(RET TYPE)FuncName(PARAM)
(RET TYPE)fun(PARAM) ------------------------->D fun是函数 3.复杂类型分析方法: 以声明的变量为中心,从右到左,从里到外;依次匹配上面A,B,C,D四个样式; 分析完毕清理;适当添加变量;下面结合具体的例子分析. 4.举例: (1) int*( * (*gopher)( int(*)(int*) ) )(int*); 首先以声明变量gopher为中心;由于它左边紧跟一个*,并且有括号使之和变量结合因此它是一个指针;这符合A,C是个样式, 再向右看,右边是圆括号,显然符合C样式,说明这是一个函数指针; 右边括号中的是参数,剩下的是返回类型; 再看右边括号中的函数参数int(*)(int*),为了和样式对照, 我们添加适当的变量让其变成int(*a)(int*b),显然这符合样式C;说明参数a 是一个函数指针, 指向的函数参数是一个int 指针;返回值是int; 我们把分析完毕的部分(*gopher)( int(*)(int*)去掉,剩下了int*( * )(int*),这剩余的部分是 gopher指向函数的返回值,我们适当添加变量变为int*( *a)(int*b);这显然又符合样式C; 说明返回值a也是一个函数指针;其指向函数的参数是一个int 指针;返回值也是一个int 指针; 综上所述,gopher是一个函数指针,指向函数(1); 函数(1)的参数是一个函数(2)指针,返回值是一个函数(3)指针, 函数(2)的参数是int*,返回值是int; 函数(3)的参数是int*,返回值也是int*。 用typedef定义这个 gopher: typedef int*( * (*gopher)( int(*)(int*)) )(int*); 以后用gopher fun1声明,则fun1就是和gopher类型一致的函数指针了。 (2)typedef double ( * (*(*fp3)())[10] )(); 首先以变量fp3为中心,由于它左边紧跟一个*,因此它是一个指针;这符合A,C是个样式, 再向右看,右边是圆括号,显然符合C样式,说明这是一个函数指针; 右边括号中的是参数,剩下的是返回类型; 再看右边括号中的函数参数为空,也就是void类型的参数; 我们把分析完毕的(*fp3)()去掉剩下double ( * (*)[10] )();适当添加变量变为double ( *(*b)[10] )(); 由于b左边紧跟一个*,因此它是一个指针;这符合A,C是个样式, 再向右看,右边是方括号,显然符合A样式,说明返回值b是一个数组指针;它指向一个数组; 那么数组中的元素是什么类型呢?我们去掉分析完毕的(*b)[10];剩下了double ( * )(); 添加变量变为double ( *a)();这显然是C的样式,说明数组中的元素是函数指针,指向的函数参数为空; 返回值为double; 综上所述:fp3是一个函数(1)指针,该函数(1)没有参数,返回一个指针, 该指针是指向一个数组,这个数组“含有10个指向函数(2)的指针” , 函数(2)不接受参,数,返回一个double值. 看上去分析很麻烦,其实分析多了不必完全按照上面的步骤进行也就很容易看懂了:) 下面是两个例子,自己分析一下吧:) (3) void* (*(*fp1)(int))[10]; fp1是一个函数指针,该函数接受一个整型参数,返回一个指针(前面多加一个*), 该指针指向含有10个void指针数组 如果分开写: typedef (void**)FUN(int); void** ppvoid = new void*[10]; (4)int (* ((*f4())[10]))(); 类似与上面的问题 f4是一个函数,返回一个指针,该指针指向含有10个函数指针的数组,这些函数返回int |