【问题标题】:Using the comma operator with the conditional operator将逗号运算符与条件运算符一起使用
【发布时间】:2025-12-24 16:15:11
【问题描述】:

我正在学习 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 , 是操作数 E1 和 E2 的 on 运算符,如 [1] 中的 E1, E2,它本身就是一个表达式。基于此,我不明白为什么 ?: 运算符的表达式 E3 的最后部分正在计算,即使表达式 E1 为真且两者兼而有之。

我的问题是:

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

【问题讨论】:

  • 您可以在不使用逗号运算符的情况下输出两件事:cout &lt;&lt; one &lt;&lt; two。这就是“流”运算符&lt;&lt; 的设计方式。使用 this 是惯用的,所以它比添加括号更好。
  • 带运算符优先级(或语法规则):cond ? E1, E2 : E3, E4; 等价于(cond ? (E1, E2) : E3), E4;
  • @Fer 你得到的答案还不够吗?您的问题仍未解决。

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


【解决方案1】:

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

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

一对用逗号分隔的表达式从左到右计算;左表达式是丢弃值表达式。与左表达式关联的每个值计算和副作用都在与右表达式关联的每个值计算和副作用之前排序。 [...]

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

【讨论】:

  • 这是否意味着表达式d() 实际上不是“被视为”?: 条件运算符的操作数,而只是被视为程序员(我自己)的另一个表达式碰巧使用逗号运算符编写?换句话说,它被解释为以下代码块? x &gt; y ? cout &lt;&lt; "x &gt; y\n" , cout &lt;&lt; "x is greater than y" : cout &lt;&lt; "x !&gt; y\n"; cout &lt;&lt; "x is not greater than y";@J。谢谢你的详细回答。
  • 也就是说,它被解释为下面的代码块? – 是的