c - 为什么函数指针可以带或不带运算符的地址?
问题描述
在《Beginning C from Novice to Professional》一书中,作者在将函数赋值给函数指针时并没有使用运算符的地址。我在编译器上输入了带有和不带有运算符地址的代码,并且两次都按预期编译和执行。为什么在企业/商业环境中会首选这种方式以及哪种方式?
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
应用于函数,因此在任何编译的表达式中,函数指示符要么隐式地,要么在地址运算符的情况下,显式转换为指向函数的指针。
甚至函数调用运算符也 ()
要求其操作数是指向函数的指针,因此您可以pfun
在不取消引用的情况下调用pfun(1, 2)
:and in首先sum(1, 2)
sum
转换为指向函数的指针,然后将函数调用运算符应用于此指针。
有一些编码约定说通过函数指针的调用应该使用解引用运算符*
,即(*pfun)(1, 2)
,同样的赋值写为pfun = ∑
。
因此,写作(*pfun)(1, 2)
不会更清楚地表明它是一个指针,因为相同的语法同样适用于函数指示符,即(*sum)(1, 2)
;在后者中,sum
首先将其转换为指向函数的指针,因为它是*
;的操作数 然后取消引用将指向函数的指针再次转换为函数指示符,然后由于它是函数调用运算符的操作数,因此再次将其转换为函数指针。
最后,请注意,pfun
作为函数指针类型的对象,&pfun
实际上会获得指针变量的地址,这几乎不是您想要的。
推荐阅读
- hydra - 无法成功使用 hydra,带有 Cookie 值的 http-post-form
- python - 在不使用列表长度的情况下迭代子列表
- pdf - mutool / mulib 编辑文本(带 ac 程序)
- sql - 每个条件返回一条记录
- android - 拍照并保存到图库
- matplotlib - 将pyplot图“保存为图”(不是图像)
- php - 如何在我的 laravel 网站中设置 adobe 连接?
- c# - TechTalk.SpecFlow.BindingException:为步骤找到不明确的步骤定义
- r - GLM LM 预测值总和和高分散
- node.js - 无法在本地通过nodejs数据库连接到PostgreSQL它突然停止在mac上工作