函数名周围的括号是啥意思?

Posted

技术标签:

【中文标题】函数名周围的括号是啥意思?【英文标题】:What do the parentheses around a function name mean?函数名周围的括号是什么意思? 【发布时间】:2012-11-16 01:13:57 【问题描述】:

在我的一个项目源文件中,我找到了这个 C 函数定义:

int (foo) (int *bar)

    return foo (bar);

注意:foo 旁边没有星号,所以它不是函数指针。或者是吗? 递归调用是怎么回事?

【问题讨论】:

不,它不是函数指针——它仍然是一个名为 foo 的常规函数​​。 这是完整的功能吗? 你有证据表明这个函数被用在了有用的上下文中吗? ...看起来像一些虚拟函数,可能只是为了查看它是否在现有源代码中编译而编写的,应该已被删除。我会删除它(如果这是该函数真正所做的),因为充其量它会是无限循环(我不确定是否允许 C 编译器优化该尾调用以跳转),最坏的情况是堆栈溢出。 C 声明中的括号有助于使语言不明确。快,a(b); 是什么?将b 声明为a 类型的变量?或者使用参数b 调用函数a?区别在于语法,如果不查找a 的声明信息,您甚至无法知道如何解析它;即那些后缀函数调用括号,或声明符周围的可选括号。 【参考方案1】:

在没有任何预处理器的情况下,foo 的签名相当于

int foo (int *bar)

我看到人们在函数名称周围加上看似不必要的括号的唯一情况是,当同时存在同名的函数和类似函数的宏,并且程序员想要防止宏扩展时。

这种做法一开始可能看起来有点奇怪,但 C 库开创了 providing some macros and functions with identical names 的先例。

这样的一个函数/宏对是isdigit()。该库可能将其定义如下:

/* the macro */
#define isdigit(c) ...

/* the function */
int (isdigit)(int c) /* avoid the macro through the use of parentheses */

  return isdigit(c); /* use the macro */

您的函数看起来与上面的几乎相同,所以我怀疑这也是您的代码中发生的事情。

【讨论】:

这里可能也是这样;我没有寻找宏...而且我不知道宏扩展不会发生在括号内,感谢您指出! @user1859094:再看一遍,几乎可以肯定这就是您的代码中发生的事情。函数内部的foo(bar)使用的是对应的宏。 @user1859094 宏扩展确实发生在括号内,但类似函数的宏的扩展只有在下一个标记是左括号时才会发生(C99,6.10.3§10),因此@987654327 @ 会被替换,但不会被替换为 (foo) (int *bar)foo 之后的下一个标记是 ) 这样的函数怎么调用?你也会用括号来称呼它吗?例如,这是否可行:(isdigit)(5)? @Greg:没错,你就是这么称呼它的。【参考方案2】:

括号并没有改变声明 - 它仍然只是定义一个名为foo的普通函数。

之所以使用它们,几乎可以肯定是因为定义了一个名为foo的类似函数的宏:

#define foo(x) ...

在函数声明中使用(foo) 可防止此宏在此处展开​​。因此,可能发生的情况是,正在定义一个函数 foo(),其主体从类似函数的宏 foo 扩展而来。

【讨论】:

很好的推论(尽管为此使用括号应该受到法律的惩罚)。 @ugoren:在函数名周围使用括号是防止类函数宏的宏扩展的唯一方法。有时它是必要的工具。 @MichaelBurr,也可以选择不使用同名的宏和函数。我知道你不能总是控制一切,但如果你达到了这个解决方案,我会说有些地方很不对劲。【参考方案3】:

括号没有意义。 您显示的代码不过是无限递归。

在定义函数指针时,您有时会看到奇怪的括号,它们确实意味着什么。但这里不是这样。

【讨论】:

显然不是;括号防止宏扩展。查看接受的答案。 @Kevin,我的回答是关于显示的代码,并且是正确的。在这里几乎所有的 C 问题中,假设未知的预处理器定义可以改变一切。在这种情况下,考虑预处理器的答案确实更好,但不会使我的答案不正确。

以上是关于函数名周围的括号是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

python中def是啥意思?

函数名后面的感叹号是啥意思?

main() 主函数是啥意思啊

函数签名中变量名前的 * 和 ** 是啥意思? [复制]

C语言中在函数名或关键字钱加下划线是啥意思?

c语言中void mainPanel()是啥意思?