对指针新认识
题外话:
这是一个在课堂中难以注意的问题,
就一个指针问题,也就把人弄得不知所措了。
最近不经意看到一个论坛,主题是的:
深入理解C语言指针的奥秘
看了之后还不觉得自己有多少不足,后细看还把自己的想法对应其例子一一复述一番,
原来什么事情都不行单看就行了。
现在,我又来回顾我看过的内容。
首先,我要更正我之前的错误想法!
错的:指针只有类似指向int数据类型指针、指向float数据类型指针、指向char数据类型指针等数据类型指针。
正确:指针可指向数据类型外,还可以指向函数,指向函数的指针叫函数指针。
现在我只知道这些,还知道别的类型指针的欢迎提示。
现在是我看到了那个论坛的收获:
收获1:右左法则
定义:首先从最里面的圆括号看起,然后往右看,再往左看。每当遇到圆括号时,就应该掉转音读方向。
一旦解析完圆括号里面所有的东西,就跳出圆括号。重复这个过程直到整个声明解析完毕。
作用:右左法则不是C标准里面的内容,它是从C标准的声明规定中归纳出来的方法。
解决如何辨识一个声明的,即,解决如何创建声明的。
注意:右左法则的前提是要求从未定义的标识符开始阅读,而不是从括号读起。之所以是未定义的标识符,是因为一个声明里面可能有多个标识符,但未定义的标识符只会有一个。
收获2:明白指针也可以指向函数
定义:一个指向函数的指针,就是一个函数指针。
例子:
1、int (*(*func)[5])(int *p);
![指向函数指针数组的指针 int (*(*func)[5])(int *p)](https://images.cnblogs.com/cnblogs_com/feminping/409873/o_未命名.bmp)
原文解释:func被一个圆括号包含,左边又有一个*,那么func是一个指针,跳出括号,右边是一个[]运算符号,说明func是一个指向数组的指针,现在往左看,左边有一个*号,说明这个数组的元素是指针,再跳出括号,右边又有一个括号,说明这个数组的元素是指向函数的指针。总结一下,就是:func是一个指向数组的指针,这个数组的元素是函数指针,这些指针指向具有int*形参,返回值为int类型的函数。
2、int (*func[5])(int *p);
![存放函数指针的数组 int (*func[5])(int *p)](https://images.cnblogs.com/cnblogs_com/feminping/409873/o_未命名2.bmp)
原文解释:func右边是一个[]运算符,说明func是一个具有5个元素的数组,func的左边有一个*,说明func的元素是指针,要注意这里的*不是修饰func的,而是修饰func[5]的,原因是[]运算符优先级比*高,func先跟[]结合,因此*修饰的是func[5]。跳出这个括号,看右边,也是一对圆括号,说明func数组的元素是函数类型的指针,它所指向的函数具有int*类型的形参,返回值类型为int。
3、int (*(*func)(int *p))[5];
![函数指针 int (*(*func)(int *p))[5]](https://images.cnblogs.com/cnblogs_com/feminping/409873/o_未命名3.bmp)
原文解释:func是一个函数指针,这类函数具有int*类型的形参,返回值是指向数组的指针,所指向的数组的元素是具有5个int元素的数组。
收获3:如何声明一个复杂指针
例子:int (*(*func)(int *p))[5];
声明一个复杂指针时,如果把整个声明写成上面所示的形式,对程序可读性是一大损害。应该用typedef来对声明逐层分解,增强可读性。
可以这样分解:
typedef int (*PARA)[5];
typedef PARA (*func)(int *);
学习过程中一定有不懂的地方,比如:
int (*(*func)[5][6])[7][8];
int (*(*(*func)(int *))[5])(int *);
int (*(*func[7][8][9])(int*))[5];
这三个如何去解释呢?
浙公网安备 33010602011771号