我正在讨论C运营商的关联性话题。
在那里我遇到了这样一个事实:函数调用操作符()
具有从左到右的关联性。但是,当表达式中出现相同优先级的多个运算符时,关联性才会发挥作用。但我找不到涉及函数调用运算符的任何示例,其中关联性起着至关重要的作用。
例如,在语句a = f(x) + g(x);
中,结果取决于评估顺序,而不是两个函数调用的关联性。
同样,调用f(g(x))
将首先评估函数g()
,然后评估函数f()
。这里我们有一个嵌套的函数调用,并且关联性再次没有任何作用。
此优先级组中的其他C运算符是数组下标[]
,postfix ++
和postfix --
。但我找不到涉及这些运算符与()
的组合的任何示例,其中关联性在表达式评估中起作用。
所以我的问题是,函数调用的关联性是否从左到右定义会影响C中的任何表达式?任何人都可以提供一个示例,其中函数调用运算符()
的关联性在表达式求值中起作用吗?
答案 0 :(得分:44)
这是一个例子,函数调用操作符的左右关联性很重要:
#include <stdio.h>
void foo(void)
{
puts("foo");
}
void (*bar(void))(void) // bar is a function that returns a pointer to a function
{
puts("bar");
return foo;
}
int main(void)
{
bar()();
return 0;
}
函数调用:
bar()();
相当于:
(bar())();
答案 1 :(得分:15)
除了@ GrzegorzSzpetkowski的回答,您还可以拥有以下内容:
void foo(void) { }
int main(void) {
void (*p[1])(void);
p[0] = foo;
p[0]();
return 0;
}
这会创建一个函数指针数组,因此您可以将数组下标运算符与函数调用运算符一起使用。
答案 2 :(得分:3)
函数应用程序关联到左侧的语句在C语言定义中完全是多余的。这&#34;关联性&#34;功能参数列表出现在函数表达式本身右侧,而必须括在括号中这一事实暗示了这一点。这意味着对于给定的函数表达式,对其参数列表的范围永远不会产生任何疑问:它从函数表达式之后的强制性左括号延伸到匹配的右括号。
函数表达式(通常只是一个标识符,但可能更复杂)本身可能是一个(裸)函数调用,如f(n)(1,0)
中所示。 (当然这要求f(n)
返回的值是可以用参数列表(1,0)
调用的东西,其中C有一些可能性和C ++更多,但这些只是语义考虑因素在解析之后来玩,因此对于关联性讨论应该忽略它们。)这意味着函数调用的语法规则是左递归的(函数部分本身可以是函数调用);这可以通过说&#34;函数调用关联到左边&#34;来表达,但事实是显而易见的。相比之下,由于所需的括号,右边部分(参数列表)不能是(裸)函数调用,因此不能有正确的递归。
例如考虑(a)(b)(c)
(我在其中加入了多余的括号以表示对称性和可能的模糊性)。这里(b)(c)
可能被称为b
(冗余括号)与参数c
的调用;但是这样的调用不能被解释为a
的参数,因为这需要(a)((b)(c))
中的附加括号。因此,在没有提及关联性的情况下,很明显(a)(b)(c)
只能表示使用参数a
调用b
,并且使用参数c
调用结果值。 / p>