三元运算符不生成错误

时间:2015-07-21 02:20:45

标签: c++ ternary-operator

我已经很熟悉三元运算符很长一段时间了,并且已经使用了一些不同的语言。我对运营商的理解是这样的:

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

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

Aren,实际上,你只是写1;i - 1;这是一个完整的陈述?我理解代码的意图是如果它大于0则递减i,但我会认为代码会生成编译器错误,因为它只是一个表达式,而不是完整的声明。我期待这样的代码:

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

4 个答案:

答案 0 :(得分:3)

这称为表达式语句。计算表达式并丢弃其值。

即使这是有效的:

42;

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

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

a = 42;
foo();

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

void f() {
    1;
}

事实上,即使这是正确的。

void f() {
    ;;;;
}

文字语句会评估其参数,但不会做任何其他事情。系统将1;视为func();。唯一的区别是虽然func();在逻辑上会产生一些副作用,1;却没有,所以它最终成为无操作。三元运算符的计算方式与if语句类似,因此仅在操作数为true时才计算第二种形式。因此:

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

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

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

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

答案 3 :(得分:1)

  

实际上,你不是只写1;或者我 - 1;

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

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

if( i > 0 ) i--;

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

i > 0 && i--;

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