转载这位的博客:
https://blog.csdn.net/bichenggui/article/details/4648843
要理解指针, 尤其是和一些其他类型修饰符放在一起的指针, 看上去很难,其实不然。
一个类型声明里会出现很多修饰符,他们就像普通的表达式一样,有优先级和结合性。只要掌握了这些规律,
分析一个复杂的指针类型就很容易了。
分析时, 先从变量名开始,然后根据修饰符的优先级结合性,一步一步分析。
下面看几个最常用的例子:
int p; // 普通的int变量
int *p; // 首先从p开始, p先与*结合,表明p是一个指针。然后再与int结合, 表明p指向的是int类型。所以p是一个指向int类型的指针。
一般的,我们称之为整型指针。
int p[3] : p先与[]结合,表明p是一个数组。然后与int结合,表明数组的元素是int类型的。因此p是一个整型的数组。
int *p[3]: []的优先级比*高,所以p先与[]结合,表明p是一个数组,再与*结合,表明数组里的元素是指针。再与int结合,表明指针指向的是int。所以p是一个数组,数组元素是整型指针(int*). 很多书里说数组就是指针,这是不确切的。数组和指针是两个不同的类型。切记!
int (*p)[3] : 这里的括号,让p与*先结合。表明p是一个指针。然后再与[]结合,表明指针指向的类型是数组。再与int结合,表明数组的元素是int类型的。 所以p是一个指向整型数组的指针。
在这里,int *[]和int (*)[]是两个不同的类型。
int **p; p为典型的二级指针。
int p(int): p首先与()结合,表明p是一个函数。进入()分析,说明该函数有一个int类型的参数。再与外面的int结合,表明函数的返回值是一个int。 所以p是一个参数类型为int,返回值为int的函数。
int (*p)(int) : 从p处开始,先与指针结合,表明p是一个指针。然后再与()结合,表明该指针指向的是一个函数。然后再与()里的int结合,表明函数有一个int类型的参数。再与最外层的int结合,表明函数的返回值是int。 这里的p是一个典型的函数指针。
int *(*p(int))[3] : 这个看上去很复杂。从p开始,先与()结合,表明p是一个函数,然后进入(),与int结合,表明函数的参数为int。
再与外面的*结合,表明函数的返回值类型是指针。然后再到最外面一层,先与[]结合,表明返回指针指向的是一个数 组。再与最外面的*结合,表明数组的元素是指针,再与最后的int结合,表明数组的元素指针指向的是int类型。
所以p是一个函数, 参数为int, 返回值为指向int* []的指针。
这确实很复杂,同样的,对于编译器的设计来说,更为复杂。但是这也是c为什么长盛不衰的原因了。因为c的设计真的很精妙。发明
c语言的是个天才。我只能这样说。