这个问题在这里已有答案:
在“从初学者到专业人员的初学者C”一书中,作者在为函数指针赋值时不使用运算符的地址。我输入了我的编译器上的代码,无论是否有运算符的地址,它都按预期编译和执行两次。为什么在企业/企业环境中首选这种方式和哪种方式?
int sum(int, int);
int main(void)
{
...
int (*pfun)(int, int);
pfun = ∑
pfun = sum;
...
}
int sum(int x, int y)
{
return x + y;
}
这是C中函数的特性.C标准说下面的(C11 3.4.1p4):
- 函数指示符是具有函数类型的表达式。除非它是
sizeof
运算符的操作数,_Alignof
运算符,65)或一元&
运算符,具有类型''函数返回类型''的函数指示符将转换为具有类型''指向函数返回类型的指针的表达式''。
即作为函数指示符的sum
在任何表达式上下文中,除非前面有&
或者所述2个运算符被转换为指向函数的指针。当然在表达式&sum
中,结果是指向函数的指针。并且ISO C不允许将sizeof
或_Alignof
应用于函数,因此在任何编译的表达式中,函数指示符可以是隐式的,或者在address-of运算符的情况下,显式转换为指向函数的指针。
甚至函数调用运算符()
也要求它的操作数是函数的指针,因此你可以在不解除引用的情况下调用pfun
:pfun(1, 2)
;在sum(1, 2)
中,sum
首先转换为指向函数的指针,然后将函数调用运算符应用于此指针。
有一些编码约定表明通过函数指针调用应该使用解除引用运算符*
,即(*pfun)(1, 2)
,并且同样将赋值写为pfun = ∑
。
因此,编写(*pfun)(1, 2)
不会更清楚它是一个指针,因为相同的语法同样适用于函数指示符,即(*sum)(1, 2)
;在后者中,sum
首先转换为指向函数的指针,因为它是*
的操作数;然后取消引用再次将指向函数的指针转换为函数指示符,然后由于它是函数调用操作符的操作数,它再次转换为函数指针。
最后,要注意pfun
是函数指针类型的对象,&pfun
实际上会得到指针变量的地址,这几乎不是你想要的。