三元运算符未生成错误

Ternary Operator Not Generating Error

本文关键字:未生 错误 运算符 三元      更新时间:2023-10-16

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

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;

这叫做表达式语句。表达式被求值,其值被丢弃。

42;

,尽管它什么也不做。只有表达式中的副作用(如i--、赋值等)才有效果。


实际上,我们使用的许多语句都是表达式语句:赋值、函数调用等:

a = 42;
foo();

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

在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,则&&需要计算,但是||已经知道它是真的

实际上,你不是在写1吗?或I - 1;

No: i--i - 1不一样。在第一种情况下,修改i的值。对于第二种情况,它不是。

如果i小于或等于零,那么你是正确的,结果'代码'将是1。然而,编译器会意识到这不是一个有用的东西,所以它应该生成相当于:

的代码:
if( i > 0 ) i--;

一些人(包括我自己)会认为以这种方式使用三元操作符是糟糕的风格。只是为了好玩,有人可能会用另一种方式来写它,这种方式也不太好(也更有可能生成编译器警告):

i > 0 && i--;

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