要理解指针, 尤其是和一些其他类型修饰符放在一起的指针, 看上去很难,其实不然。

一个类型声明里会出现很多修饰符,他们就像普通的表达式一样,有优先级和结合性。只要掌握了这些规律,

分析一个复杂的指针类型就很容易了。

 

分析时, 先从变量名开始,然后根据修饰符的优先级结合性,一步一步分析。

下面看几个最常用的例子:

 

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语言的是个天才。我只能这样说。