在“从新手到专业人士的C入门”一书中,当将功能分配给功能指针时,作者不使用运算符的地址。我在编译器上键入了有无操作符地址的代码,都按预期进行了编译和执行。为什么会这样?在企业/业务环境中首选哪种方式?
int sum(int, int);
int main(void)
{
...
int (*pfun)(int, int);
pfun = ∑
pfun = sum;
...
}
int sum(int x, int y)
{
return x + y;
}
答案 0 :(得分:3)
这是C语言中功能的独特之处。C标准规定了以下(C11 3.4.1p4):
- 函数指示符是具有函数类型的表达式。除非它是
sizeof
运算符,_Alignof
运算符(65)或一元&
运算符的操作数,否则类型为“函数返回类型”的函数指示符将转换为具有“指向函数返回类型的指针”类型的表达式。
即作为功能指示符的sum
在 any 表达式上下文中,除非以&
开头或将上述2个运算符转换为函数指针。当然,在表达式&sum
中,结果是指向函数的指针。而且ISO C不允许将sizeof
或_Alignof
应用于函数,因此在任何编译表达式中,函数指示符是隐式的,或者在地址的情况下-of运算符,明确转换为指向函数的指针。
即使函数调用运算符 ()
也需要,其操作数是函数指针,因此您可以调用{{ 1}},而不必取消引用:pfun
;在pfun(1, 2)
中,sum(1, 2)
首先转换为指向函数的指针,然后将函数调用运算符应用于该指针。
有些编码约定说,通过函数指针进行的调用应使用解引用运算符sum
,即*
,并且类似地,将赋值写为(*pfun)(1, 2)
。
这样,写pfun = ∑
并不能更清楚地表明它是一个指针,因为相同的语法对于功能指示符(即(*pfun)(1, 2)
)同样有效。在后者中,(*sum)(1, 2)
首先转换为指向函数的指针,因为它是sum
的操作数;然后取消引用会再次将指向函数的指针转换为函数指定符,然后由于它是函数调用操作符的操作数,因此它将再次转换为函数指针。
最后,请注意*
是功能指针类型的对象 ,pfun
实际上将获得指针变量的地址,这几乎是您想要的。