指针可以指向各种内存元素类型,因而存在变化多样的语法定义,靠死记硬背难以分辨,特别是一些复杂及嵌套定义。要弄清指针到底指向什么类型的内存变量,有个小窍门:把指针声明中的指针变量名和之前的指针声明符*去掉,剩下的就是指针所指内存的类型。比如:
int *ptr; //去掉 *ptr,指针所指内存的类型是int
char *ptr; //指针所指向的内存类型是char
int **ptr; //指针所指内存的类型是 int *
int (*ptr)[3]; //指针指向类型 int [3](代表数组的表达),即指向整型数组的指针。
int *(*ptr)[4]; //指针所指向的的类型是 int *[4] ,即指向指针数组的指针
……
不过也存在个别表达形式难以直接套用,比如:
1)指针数组与指向数组的指针:
int *ptr[3]; //指针数组
int (*ptr)[3]; //指向数组的指针
2)返回指针型的函数与指向函数的指针
int* fun1(char*,int); //定义函数fun1,其返回值为指向int类型的指针
int (*pfun1)(char*,int); //定义指针pfun,指向某函数,函数返回int值
要区分这两种情况,只要记住:*号优先级等同于函数定义的()和数组下标的[],如果表达式中它们同时出现且没有额外()影响,遵循由右向左结合的原则。
比如对int *ptr[3],由右向左,它首先是一个数组,剩下的int *ptr说明数组元素是指针型,因此它整体是一个指针数组。而对int(*ptr)[3],受额外的()括号影响,*ptr先结合,所以它首先是一个指针,剩下的int [3]代表数组,所以它是指向数组的指针。
同样表达式int *fun1()中,*与()处于同样优先级,由右向左首先是函数,然后返回值为int *。而int (*pfun1)()中,受第一个额外的括号影响,*pfun1先结合,首先是一个指针,剩下int ()代表返回值为int型的函数,因而整体是一个指向函数的指针。
掌握这个小窍门,就基本不必为辨别各种指针定义形式而烦恼了。至于更加稀奇古怪的形式,这辈子真有幸碰到的话,google一下也就可以,没必要细究了。指针是人自己定义的工具,不是科研对象。