说明
整理自《C陷阱与缺陷》(C Traps and Pitfalls) 第2章
学习笔记——根据本人理解,加以表述,并非完全摘抄。
1、区分
float *g(), (*h)();
注解:
很明显()的优先级高于 *,所以*g()相当于*( g() ),这样就很明确了,g是一个函数,其返回值是float *型的值,即指向浮点数的指针。
而h是一个函数指针,根据其定义,该指针可用于指向返回值为浮点类型的函数。
2、类型转换符
float (*h)();
想要获得该类型的类型转换符,只要把声明中的变量名和声明末尾的分号去掉,再将整个剩余的部分加上括号。即:( float (*)() )
3、函数指针的简写问题
假设有一个返回值为int型的函数,定义一个函数指针指向该函数,并且调用该函数的方法:
int (*pf)() = &add;
pf();
直接用指针变量加括号(可能有参数)即可调用指向的函数,但我们要知道这是简写形式,完整的调用方式应该是(*pf)()
,只是ANSI C标准允许这样简写,我们也基本都使用简写形式调用函数。
但是我们使用函数指针时一定要注意括号问题:*pf两边的括号千万不能遗漏。
如果遗漏了就变成*pf() —> *( pf() ) —> *( (*pf)() )
4、理解一个复杂的表达式
(*(void (*)())0)();
其中一部分应该很熟悉(void (*)())
,这就是刚刚讲到的类型转换符,可见这是讲常数0转换为“指向返回值为void类型的函数的指针”,即将0转换成了函数指针。
既然是个函数指针那我们就应该想到函数指针的使用,很容易联想到调用的非简写形式,即(*pf)()
,那么该表达式的结构就清楚了。