为什么在有或没有运算符地址的情况下都可以使用函数指针? [英] Why can function pointers be used with or without the address of operator?

查看:107
本文介绍了为什么在有或没有运算符地址的情况下都可以使用函数指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在从新手到专业人士的C入门"一书中,当向函数指针分配函数时,作者不使用运算符的地址.我在编译器上输入了带或不带运算符地址的代码,并且两次都按预期进行了编译和执行.为什么会这样?在企业/业务环境中首选哪种方式?

In the book, "Beginning C from Novice to Professional", the author does not use the address of operator when assigning a function to a function pointer. I typed in the code on my compiler both with and without the address of operator and it compiled and performed as expected both times. Why is this and which way would be preferred in an enterprise/business setting?

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标准说以下

This is a peculiarity of functions in C. The C standard says the following (C11 3.4.1p4):

  1. 函数指示符是具有函数类型的表达式.除非它是sizeof运算符,_Alignof运算符(65)或一元&运算符的操作数,否则类型为"function returning type"的函数指示符将转换为类型为' 指向函数返回类型的指针".
  1. A function designator is an expression that has function type. Except when it is the operand of the sizeof operator, the _Alignof operator, 65) or the unary & operator, a function designator with type ''function returning type'' is converted to an expression that has type ''pointer to function returning type''.

即作为功​​能指示符的sum any 表达式上下文中,除非以&开头或将上述2个运算符转换为指向函数的指针.当然,在表达式&sum中,结果是指向函数的指针.而且ISO C不允许将sizeof_Alignof应用于函数,因此在任何编译表达式中,函数指示符是隐式的,或者在地址运算符的情况下,显式转换为指向函数的指针.

I.e. sum that is a function designator is in any expression context, except when preceded by & or the said 2 operators is converted to a pointer to function. Of course in the expression &sum, the result is a pointer to a function. And ISO C does not allow sizeof or _Alignof be applied to a function, so in any expression that compiles, a function designator is either implicitly, or in the case of address-of operator, explicitly converted to a pointer to a function.

即使函数调用运算符 () 需要,其操作数也是函数的指针,因此您可以调用pfun而不用取消引用:pfun(1, 2);在sum(1, 2)中,sum首先被 转换为指向函数的指针,然后将函数调用运算符应用于该指针.

Even the function call operator () requires that its operand be a pointer to function, hence you can call pfun without dereferencing: pfun(1, 2); and in sum(1, 2) sum is first converted to a pointer to a function, and then the function call operator is applied to this pointer.

有些编码约定说,通过函数指针进行的调用应使用取消引用运算符*,即(*pfun)(1, 2),并且类似地,将赋值写为pfun = ∑.

There are coding conventions that say that a call through a function pointer should use the dereference operator *, i.e. (*pfun)(1, 2), and likewise that the assignment be written as pfun = ∑.

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

As such, writing (*pfun)(1, 2) would not make it clearer that it is a pointer as the same syntax would equally work for a function designator, i.e. (*sum)(1, 2); in the latter, sum is first converted to a pointer to a function since it is an operand to *; then the dereference converts the pointer to function to a function designator again, and then since it is an operand to a function call operator, it is converted to a function pointer again.

最后,请注意pfun 是函数指针类型的对象&pfun实际上将获得指针变量的地址,这几乎是您想要的.

Lastly, beware that pfun being an object of function pointer type, &pfun would actually get the address of the pointer variable, which is almost never what you wanted.

这篇关于为什么在有或没有运算符地址的情况下都可以使用函数指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆