C中函数调用操作符的相关性

时间:2015-08-10 11:01:29

标签: c associativity

我正在讨论C运营商的关联性话题。

在那里我遇到了这样一个事实:函数调用操作符()具有从左到右的关联性。但是,当表达式中出现相同优先级的多个运算符时,关联性才会发挥作用。但我找不到涉及函数调用运算符的任何示例,其中关联性起着至关重要的作用。

例如,在语句a = f(x) + g(x);中,结果取决于评估顺序,而不是两个函数调用的关联性。 同样,调用f(g(x))将首先评估函数g(),然后评估函数f()。这里我们有一个嵌套的函数调用,并且关联性再次没有任何作用。

此优先级组中的其他C运算符是数组下标[]postfix ++postfix --。但我找不到涉及这些运算符与()的组合的任何示例,其中关联性在表达式评估中起作用。

所以我的问题是,函数调用的关联性是否从左到右定义会影响C中的任何表达式?任何人都可以提供一个示例,其中函数调用运算符()的关联性在表达式求值中起作用吗?

3 个答案:

答案 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>