三元条件和赋值运算符优先级
Posted
技术标签:
【中文标题】三元条件和赋值运算符优先级【英文标题】:Ternary conditional and assignment operator precedence 【发布时间】:2011-11-21 21:35:48 【问题描述】:我对直接赋值和三元条件运算符优先级感到困惑:
#include<stdio.h>
int main(void)
int j, k;
j = k = 0;
(1 ? j : k) = 1; // first
printf("%d %d\n", j, k);
j = k = 0;
1 ? j : k = 1; // second
printf("%d %d\n", j, k);
return 0;
我希望输出是:
1 0
1 0
但它恰好是:
1 0
0 0
另外我收到了这个警告:
main.cpp:20: 警告:语句无效
这与我评论为第二行有关。
由于直接赋值运算符的优先级低于三元条件运算符,我希望注释为 first 和 second 的行是等价的。但可惜不是这样的。
我用 g++ --version (Ubuntu 4.4.3-4ubuntu5) 4.4.3 试过这个
【问题讨论】:
C++ 是奇迹还是野兽?在我用它编程了一半之后,我仍然会被抓到不知道像这样的简单表达式的含义。我必须在标准中查看这个。 【参考方案1】:C/C++ 语言中的运算符优先级不是由表或数字定义的,而是由语法定义的。以下是C++0x draft 5.16 条件运算符 [expr.cond] 章中条件运算符的语法:
条件表达式: 逻辑或表达式 逻辑或表达式?表达式:赋值表达式因此,当您在双冒号的左侧使用赋值时,像this one 这样的优先级表是正确的,但在右侧使用时则不正确。我不知道这种不对称的原因是什么。这可能是一个历史原因:在 C 中,条件结果不是左值,因此给它赋值是没有意义的,当时允许不带括号的赋值可能看起来很聪明。
【讨论】:
为什么冒号右侧的链接表(将 ?: 和 = 组合在一起)不正确? @foxcub 当前版本的表格是正确的。赋值与表中的条件具有相同的优先级,并且关联性是从右到左,导致赋值在条件之前正确完成。表was incorrect at the time of the answer,声明条件优先级高于赋值。 C++ 语法被定义为句法文法,但该文法被设计为与简单的优先表一致。您说该表“在冒号左侧使用时不正确”,但据此推理,在]
左侧使用表达式(例如 a[b+c]
)时,优先级也不正确。优先级表的主张是 两个运算符在他们期望操作数的地方看到的子表达式被赋予具有更高优先级的那个(并且关联被关联性打破)。 永远不会违反此主张. ?:
和 =
具有相同的优先级。【参考方案2】:
第二行相当于:
1 ? (j) : (k = 1);
同理:
j;
同理:
;
关键是三元条件运算符的两个操作数可以是表达式,所以这里不涉及运算符优先级。只是第二个操作数是赋值表达式k = 1
。
【讨论】:
nod 问题根本与运算符优先级无关——它是 ?: 是一个短路运算符。 @KazDragon:我澄清了——关键是操作数是表达式,所以第二个操作数是整个赋值表达式。 (顺便说一下,所有标准的逻辑二元运算符都是短路的。短路是指对条件的评估,而不是结果语句。) 你是对的,但问题是:为什么它等于 1 ? (j) : (k = 1);而不是 (1 ? j : k) = 1,当条件应该比赋值具有更高的优先级时? @Suma:“优先级”没有出现,因为只涉及一个运算符,其操作数是表达式。您已经引用了解释这一点的语法的相关部分。 涉及多个运算符(赋值也是运算符)。您没有解释为什么赋值表达式优先于条件表达式(常用的优先级表也没有解释这一点)。【参考方案3】:(1 ? j : k) = 1;
等价于,
if(true) j = 1;
else k = 1;
还有,
1 ? j : k = 1;
等价于,
if(true) j; // warning: statement has no effect
else k = 1;
【讨论】:
【参考方案4】:第二种情况,
1 ? j : k = 1;
被评估为:
(1) ? (j) : (k = 1);
由于一个计算结果为true
,因此表达式计算结果为j
,它什么都不做。
【讨论】:
以上是关于三元条件和赋值运算符优先级的主要内容,如果未能解决你的问题,请参考以下文章