繁体   English   中英

条件运算符的评估顺序

[英]Order of evaluation for conditional operator

众所周知,赋值=和条件?:运算符都具有正确的关联性。 在以下代码示例中:

#include <stdio.h>

int main(void)
{
    int a, b, c, d;

    a = b = c = d = 1;
    1 ? a++ : b ? c++ : d;

    printf("%d %d %d %d\n", a, b, c, d);
    return 0;
}

分配:

a = b = c = d = 1;

等效于:

a = (b = (c = (d = 1)));

并相应地:

1 ? a++ : b ? c++ : d;

是相同的:

1 ? a++ : (b ? c++ : d);

标准对这最后一种情况怎么说? 它是否保证从左到右评估这样的组合表达式(因此不评估c++部分),与赋值相反?

保证?:的求值顺序:首先对第一个操作数求值,然后根据第一个操作数为true求值第二个或第三个操作数。

您主要对运算符优先级/关联性评估顺序之间的关系感到困惑。 他们扮演着不同的角色。 前者决定如何对运算符进行分组,而后者则决定首先评估哪个子表达式。

考虑表达式a * b + c * d ,优先级规则意味着它等效于(a * b) + (c * d) 但是是否可以保证编译器在c * d之前对a * b进行求值? 答案是否定的,在此示例中,运算符+不保证评估顺序。

条件运算符?:是为数不多的具有指定评估顺序的运算符之一。 (其余的&&|| ,和, )。


在你的例子中

1 ? a++ : b ? c++ : d;
1 ? a++ : (b ? c++ : d);

总是等效,在两个表达式, 1首先计算,并且因为它是真实的, a++接下来评价结束。

关联性优先级未定义评估顺序 这些概念是完全无关的。 C语言中的求值顺序排序规则定义,而不是由优先级或关联性定义。

确实, a = b = c = d = 1; 关联a = (b = (c = (d = 1))); ,但这并不意味着应该首先评估d = 1 ,尤其是在C语言中,赋值运算符的结果为rvalue。

关联性只是说c应该收到转换为d类型的值1 (“好像”是从d读取的)。 但这并不意味着d = 1应该首先完成。 在您的示例中,所有变量都具有相同的类型,这意味着整个对象等于a = 1; b = 1; c = 1; d = 1; a = 1; b = 1; c = 1; d = 1; 以任何顺序排列。 a = b = c = d = 1表达式内部没有排序。

相同的逻辑适用于?:运算符。 它的关联性只是告诉您哪个操作数属于哪个运算符。 分组的确是1 ? a++ : (b ? c++ : d); 1 ? a++ : (b ? c++ : d); 但是关联性不会告诉您有关评估顺序的任何信息。 ?:运算符中的评估顺序是分别和独立定义的:始终首先评估(排序)条件,然后评估一个(只有一个)分支。 在您的示例1中,首先对a++求值,然后对a++求值,其结果成为整个表达式的结果。 (b ? c++ : d)部分甚至没有被触及。

1 ? a++ : b ? c++ : d;

相当于

if (1) {
    a++;
}
else {
    if (b) {
        c++;
    }
    else {
        d;
    }
}

因此,输出将是

2 1 1 1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM