三元运算符不产生错误

Ternary Operator Not Generating Error

我熟悉三元运算符已经有一段时间了,并且使用过几种不同的语言。我对运算符的理解是这样的:

condition ? expr1 : expr2 但是,在C++中,下面的代码是合法的:

int i = 45;
(i > 0) ? i-- : 1;

实际上,您不只是在写 1;i - 1; 这是一个完整的陈述吗?我知道代码的目的是减少 i 如果它大于 0,但我认为代码会生成编译器错误,因为它只是一个表达式,而不是一个完整的语句。我期望这样的代码:

int i = 45;
i = (i > 0) ? i - 1 : i;

这是一个有效的表达。您可能收到警告,因为您没有保存表达式的结果,但您的 i-- 您的语句确实有效。

这叫做表达式语句。计算表达式并丢弃其值。

这也是有效的:

42;

虽然它什么都不做。只有表达式中的副作用(如 i--、赋值等)才有效。


其实我们使用的很多语句都是表达式语句:赋值、函数调用等:

a = 42;
foo();

在 C++ 中,像 1 这样的表达式是完全有效的语句,没有副作用。你可以非常可行地编写这个函数:

void f() {
    1;
}

事实上,这也是正确的。

void f() {
    ;;;;
}

文字语句计算其参数,但仅此而已。系统将 1; 视为与 func(); 一样。唯一的区别是,虽然 func(); 在逻辑上会产生一些副作用,但 1; 不会,所以它最终成为一个空操作。三元运算符的计算类似于 if 语句,因此仅当操作数为真时才计算第二种形式。因此:

(i > 0) ? i-- : 1;

如果 i 大于 0,则计算第二种形式。当它被评估时,它会产生副作用,将 i 减 1。否则,将评估第三种形式,它什么都不做。虽然这段代码有效,但它的可读性并不令人难以置信,因此虽然它是不错的玩具代码,但真正的 if 语句非常适合这种情况。出于同样的原因,这一行将具有相同的效果,但同样不可读,因此不受欢迎。

((i > 0) && (i--)) || 1;

假设您没有覆盖布尔运算符,此代码将短路并表现得像三元运算符。如果 i 不大于 0,则 && 不需要评估其第二个操作数,因为 && 为假,但 ||必须,因为它可能是真的。相反,如果 i 大于 0,则 && 需要评估,但 ||已经知道这是真的了。

Aren't you, in effect, just writing 1; or i - 1;

否:i--i - 1 不同。第一种情况,修改了i的值。在第二种情况下它不是。

如果 i 小于或等于零,那么结果 'code' 将是 1 是正确的。然而,编译器会意识到执行这不是一件有用的事情,因此它应该生成等同于以下内容的代码:

if( i > 0 ) i--;

有些人(包括我自己)会认为以这种方式使用三元运算符是不好的风格。只是为了好玩,这是另一种写法,也不是很好(也更有可能产生编译器警告):

i > 0 && i--;

归根结底,风格是个人喜好问题。在大多数情况下,编译器将决定将代码转换为汇编的最佳方式。因此,您应该为自己编写清晰简洁的代码。