[英]Ternary operator in loop conditional: evaluation order / op. precedence unclear
[英]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.