c++ - 将逗号运算符与条件运算符一起使用

标签 c++ conditional-statements operator-keyword comma-operator

我正在学习 C++,在使用 ?: 运算符时偶然发现了以下行为。条件运算符的语法如下 E1 ? E2 : E3,其中 E1、E2 和 E3 是表达式[1]、[2]。我从这段代码开始:

#include <iostream>

using namespace std;

int main(){
    int x = 20, y = 25;
    x > y ? cout << "x > y\n" , cout << "x is greater than y" : cout << "x !> y\n", cout << "x is not greater than y";
    return 0;
}

和输出:

x !> y
x is not greater than y

这就是我所期待的结果。但是,当我将值更改为 int x = 25, y = 20 以使 x 大于 y 时,我得到以下输出:

x > y
x is greater than y
x is not greater than y

但我期待的是:

x > y
x is greater than y

因此,即使表达式 E1 的结果为 true,也会计算表达式 E3 的最后部分。

但是,当我将 E2 和 E3 放在括号内时,程序的输出在两种情况下都符合预期:当 x > y 和 x < y 时。根据 [1],逗号 , 是带有操作数 E1 和 E2 的 on 运算符,如 E1, E2 中所示,它本身就是一个表达式,根据 [1]。基于此,我不明白为什么即使表达式 E1 为 true 并且两者都为 true,也会计算 ?: 运算符的表达式 E3 的最后部分。

我的问题是:

1) 我是否正确使用了条件运算符 ?:?

2)这种意外结果发生的机制是什么?

3)为什么使用括号可以解决问题(或者至少符合我的期望)?

我正在使用:gcc版本5.4.0 20160609(Ubuntu 5.4.0-6ubuntu1~16.04.11)

非常感谢。

[1] https://en.cppreference.com/w/cpp/language/expressions

[2] https://en.cppreference.com/w/cpp/language/operator_other

最佳答案

为了简单起见,让我们考虑一个更容易阅读的语句:

foo ? a(), b() : c(), d();

我们遇到的第一个运算符是条件运算符( §7.6.16 ):

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

第二个操作数可以是表达式,a(), b() 是复合表达式。 然而,第三个操作数只能是赋值表达式( §7.6.19 ):

assignment-expression:
    conditional-expression
    yield-expression
    throw-expression
    logical-or-expression assignment-operator initializer-clause
assignment-operator: one of
    =  *=  /=  %=   +=  -=  >>=  <<=  &=  ^=  |=
c(), d()

不是其中之一,而是逗号表达式 (§ 7.6.20/1 ):

expression:
    assignment-expression
    expression , assignment-expression

A pair of expressions separated by a comma is evaluated left-to-right; the left expression is a discarded-value expression. Every value computation and side effect associated with the left expression is sequenced before every value computation and side effect associated with the right expression. [...]

因此,整个语句中最后一个逗号运算符左侧的所有内容都是一个废弃值表达式,该表达式在逗号运算符右侧之前进行计算(并丢弃其结果)。

关于c++ - 将逗号运算符与条件运算符一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59588427/

相关文章:

c++ - 排序中的 < 运算符断言无效

c++ - 赋值运算符重载问题

iphone - 我如何使用 NSConditionLock?或 NSCondition

C++(在 Linux 下)程序没有给出预期的输出(定时器)

c++ - ISO C++ 中是否有任何关于 i18n 和 L10n 的好的引用资料?

c++ - 动态分配对象数组

javascript - ejs 模板中的 If-else 简写?

f# - 有条件地在 F# 中的正向管道链中应用过滤器?

c++ - & 符号 '&' 参数末尾的运算符

c++ - 使用正则表达式在 C++ 中提取匹配的字符串