【发布时间】:2021-04-29 16:20:30
【问题描述】:
对于三元运算符,为什么会编译:
a > b ? a=4 : ' ';
但是这个没有:
a > b ? ' ' : b=4;
需要左值作为赋值的左操作数
也就是说,true case 与 false case 的赋值有何不同?
【问题讨论】:
对于三元运算符,为什么会编译:
a > b ? a=4 : ' ';
但是这个没有:
a > b ? ' ' : b=4;
需要左值作为赋值的左操作数
也就是说,true case 与 false case 的赋值有何不同?
【问题讨论】:
:? 的运算符优先级高于赋值运算符。所以后者相当于:
(a > b ? ' ' : b)=4;
这显然是非法的。
【讨论】:
a > b ? (a = 4) : ' '; 或a > b ? ' ' : (b = 4);(这是对称的,即使在第一种情况下不是绝对必要的)。括号避免了编译器和人类代码阅读器产生歧义的所有风险。只做一个分配似乎有点可疑(为什么将 control-D 分配给这个表达式所分配的任何东西),但如果没有比显示更多的代码,很难知道。如果没有分配或以其他方式使用表达式,那么使用三元运算符是完全不合适的——使用if 语句。
这与条件运算符的正式定义有关。来自C standard 的第 6.5.15 节:
conditional-expression: logical-OR-expression logical-OR-expression ? expression : conditional-expression
条件的第二个子句可以是任何表达式,而第三个子句只能是一个条件表达式(其中 as assignment 不是)。换句话说,条件运算符?: 的优先级高于赋值运算符=。
所以这个:
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 计算第一个操作数;之间有一个序列点 它的评估和第二个或第三个操作数的评估 (以评估为准)。只有当 首先比较不等于0;仅在以下情况下评估第三个操作数 第一个比较等于 0; 结果是第二个的值 或第三个操作数(以被评估者为准),转换为类型 如下所述
在 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
【讨论】: