为什么函数指针可以使用或不使用运算符的地址? [重复]

问题描述 投票:4回答:1

在“从初学者到专业人员的初学者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 function-pointers address-operator
1个回答
3
投票

这是C中函数的特性.C标准说下面的(C11 3.4.1p4)

  1. 函数指示符是具有函数类型的表达式。除非它是sizeof运算符的操作数,_Alignof运算符,65)或一元&运算符,具有类型''函数返回类型''的函数指示符将转换为具有类型''指向函数返回类型的指针的表达式''。

即作为函数指示符的sum在任何表达式上下文中,除非前面有&或者所述2个运算符被转换为指向函数的指针。当然在表达式&sum中,结果是指向函数的指针。并且ISO C不允许将sizeof_Alignof应用于函数,因此在任何编译的表达式中,函数指示符可以是隐式的,或者在address-of运算符的情况下,显式转换为指向函数的指针。

甚至函数调用运算符()也要求它的操作数是函数的指针,因此你可以在不解除引用的情况下调用pfunpfun(1, 2);在sum(1, 2)中,sum首先转换为指向函数的指针,然后将函数调用运算符应用于此指针。

有一些编码约定表明通过函数指针调用应该使用解除引用运算符*,即(*pfun)(1, 2),并且同样将赋值写为pfun = ∑

因此,编写(*pfun)(1, 2)不会更清楚它是一个指针,因为相同的语法同样适用于函数指示符,即(*sum)(1, 2);在后者中,sum首先转换为指向函数的指针,因为它是*的操作数;然后取消引用再次将指向函数的指针转换为函数指示符,然后由于它是函数调用操作符的操作数,它再次转换为函数指针。

最后,要注意pfun是函数指针类型的对象,&pfun实际上会得到指针变量的地址,这几乎不是你想要的。

© www.soinside.com 2019 - 2024. All rights reserved.