三元运算符中的赋值

Assignment in ternary operator

对于三元运算符,为什么以下编译:

a > b ? a=4 : ' ';

但是这个没有:

a > b ? ' ' : b=4;

lvalue required as left operand of assignment

也就是说,true 的情况与 false 的情况有何不同?

:? 的运算符优先级高于赋值运算符。所以后者相当于:

(a > b ? ' ' : b)=4;

这显然是非法的。

这与条件运算符的正式定义有关。来自 C standard 的第 6.5.15 节:

conditional-expression:
  logical-OR-expression
  logical-OR-expression ? expression : conditional-expression

条件语句的第二个子句可以是任何表达式,而第三个子句只能是一个条件表达式(赋值不是)。换句话说,条件运算符 ?: 的优先级高于赋值运算符 =.

所以这个:

a > b ? a=4 : ' '

与此相同:

(a > b) ? (a=4) : (' ')

但是这个:

a > b ? ' ' : b=4;

与此相同:

((a > b) ? (' ') : b)=4;

并且条件运算符的结果不能赋值给(即它不是左值)所以你得到一个错误。

如果你添加括号你可以得到编译的东西:

a > b ? ' ' : (b=4);

当然,这些语句看起来不像是条件语句的最佳用例,可能应该重写为:

if (a>b) a=4;

并且:

if (a<=b) b=4;

这是你应该知道的C和C++之间的本质区别。:)

在 C 中,条件(三元)运算符定义如下

conditional-expression:
    logical-OR-expression
    logical-OR-expression ? expression : conditional-expression

而在 C++ 中就像

conditional-expression:
    logical-or-expression
    logical-or-expression ? expression : assignment-expression

所以在 C 中这个语句

a > b ? ' ' : b=4;

等同于

( a > b ? ' ' : b ) = 4;

所以编译器会报错,因为你不能将一个值赋给其他值。

来自 C 标准(6.5.15 条件运算符)

4 The first operand is evaluated; there is a sequence point between its evaluation and the evaluation of the second or third operand (whichever is evaluated). The second operand is evaluated only if the first compares unequal to 0; the third operand is evaluated only if the first compares equal to 0; the result is the value of the second or third operand (whichever is evaluated), converted to the type described below

在 C++ 中,此语句等效于

a > b ? ' ' : ( b=4 );

并且是一个有效的陈述。

这是一个演示程序

#include <iostream>

int main() 
{
    int a = 0, b = 1;
    
    a > b ? ' ' : b=4;
    
    std::cout << "b = " << b << '\n';
    
    return 0;
}

它的输出是

b = 4