三元运算符和赋值运算符

5

C/C++中,条件运算符和赋值运算符的优先级是否相同?

Luchian Grigore的回答指出,像下面这种情况:

a ? b : c = d

将始终被推断为

a ? b : ( c = d )

由于等号和三目运算符都是从右向左结合的,因此在C++中。
k =  21 > 3 ? j = 12 : j = 10;

并且。
k = 1 > 3 ? j = 12 : j = 10;

两种方式都可以。

在C语言中,

k = 21 > 3 ? 12 : j = 10

返回错误

invalid lvalue in assignment.

上面的内容应该被理解为(并且不返回错误)。
k=  21 > 3 ? 12 : ( j = 10 )

我猜现在它正在被分组为:
k = ( 21 > 3 ? 12 : j ) = 10

由于在C语言中(而不是C++),三目运算符不能返回lvalue,因此会出现错误。有人能告诉我在这种情况下运算符是如何分组的吗?


我会尽量避免这样的好奇心,而是写成: 如果(1>3) k = j = 12 否则 k = j = 10 - Sceptical Jule
在C和C++中,a ? b : c = d不同的!在其中一个中是a ? b : (c = d),而在另一个中是(a ? b : c) = d - Kerrek SB
我认为它实际上被处理为k=(21>3?12:j=10) - David Rodríguez - dribeas
@David Rodríguez - dribeas http://ideone.com/nbJYZn - Zxcv Mnb
@ZxcvMnb:这就是把C/C++看作同一种语言提出问题的问题。我不是C语言专家,所以无论C编译器说什么都可能是正确的,但在C++中我的评论是正确的。 - David Rodríguez - dribeas
显示剩余4条评论
2个回答

2

您链接的问题("C/C++三目运算符是否与赋值运算符优先级相同?"),@hvd所提供的答案说明了问题。

C++和C中?:的语法不同。

在C++中,右侧操作数允许是一个赋值表达式(因此编译器[贪心地]将=视为?:的一部分),而在C中,右侧操作数则是一个条件表达式。因此,在C中,一旦编译器遇到=,就会完成对?:的分析,并将其视为k = ( 21 > 3 ? 12 : j ) = 10


由于12不是一个左值,当您尝试编译12 = 10时,您将会得到一个编译器错误。 - Lundin
@Lundin 我认为问题在于 (21 > 3 ? 12 : j) 不是一个左值,因此通过用 j 替换 12,我们仍然会得到相同的错误。 - Zxcv Mnb
在 C 中,逻辑或表达式?表达式:条件表达式,<br> 在 C++ 中,逻辑或表达式?表达式:赋值表达式。<br> 因此,C 编译器愉快地将 j 视为条件表达式并继续执行。谢谢大家。 - Zxcv Mnb

0

k=21>3?12:(j=10) 被评估为

if ( 21 > 3 )
    k = 12;
else
    k = ( j = 10 );

由于 21>3true,因此 else 条件不会被评估,j 具有未定义的值(或者在此语句之前具有的任何值)。


抱歉,问题已经被编辑。原始问题是,为什么在C中"k = 21 > 3 ? 12 : j = 10"不会被解释为"k = 21 > 3 ? 12 : (j = 10)"? - Zxcv Mnb
如果在j=10周围没有括号,从左到右的计算会将j赋值给k,然后再进行额外的赋值。由于成功情况下有一个常量(不是lvalue),编译器尝试解析将10分配给非lvalue并发出错误。 - unxnut

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接