【问题标题】:Something we found when using comma in condition ternary operator? [duplicate]我们在条件三元运算符中使用逗号时发现了什么? [复制]
【发布时间】:2012-02-29 15:56:10
【问题描述】:

嗯,我有一个关于三元运算符中的逗号的问题。 废话不多说,代码如下:

void test_comma_in_condition(void)
{
    int ia, ib, ic;

    ia = ib = ic = 0;
    bool condition=true;

    cout<<"Original:"<<endl;
    cout<<"ia: "<<ia<<endl;
    cout<<"ib: "<<ib<<endl;
    condition?(ia=1, ib=2):(ia=11, ib=12);
    cout<<"After:"<<endl;
    cout<<"ia: "<<ia<<endl;
    cout<<"ib: "<<ib<<endl;

    ia = ib = ic = 0;
    condition?ia=1, ib=2, ic=3:ib=22,ia=21, ic=23;
    cout<<"The operation must be bracketed, or you'll see..."<<endl;
    cout<<"ia: "<<ia<<endl;
    cout<<"ib: "<<ib<<endl;
    cout<<"ic: "<<ic<<endl;

    condition?ia=1, ib=2, ic=3:ia=21, ib=22, ic=23;
    cout<<"The operation must be bracketed, or you'll see..."<<endl;
    cout<<"ia: "<<ia<<endl;
    cout<<"ib: "<<ib<<endl;
    cout<<"ic: "<<ic<<endl; 

    return;
}

输出会是这样的:

Original:
ia: 0
ib: 0
After:
ia: 1
ib: 2
The operation must be bracketed, or you'll see...
ia: 21
ib: 2
ic: 23
The operation must be bracketed, or you'll see...
ia: 1
ib: 22
ic: 23

这合法吗?

【问题讨论】:

  • 你说a ? b : c, d 应该是a ? b : (c, d) 而不是(a ? b : c), d。不考虑哪个是正确的问题,您怀疑编译器的原因是什么?
  • 是的,它是合法的——但也是不可读的。

标签: c++ ternary


【解决方案1】:

这是运算符优先级的问题。你的表情:

condition?ia=1, ib=2, ic=3:ib=22,ia=21, ic=23;

被编译器理解为:

(condition?(ia=1, ib=2, ic=3):(ib=22)),ia=21, ic=23;

此时您应该可以看到为什么会得到程序输出。

【讨论】:

  • 扮演魔鬼的拥护者,但如果这是优先级问题,为什么 , 在条件表达式的“中间”似乎比 ?: 具有更高的优先级,但在条件表达式?
  • 我为你的答案 +1 了,因为它回答了这个好问题 - 逗号表达式是 expression 的一部分,但不是 assignment-expression 的一部分。
  • 这里不能真正调用优先级。形式上,C++ 运算符不是按优先级排序的,而是按语法中的不同产生式排序的。大多数情况下,效果与标准中产生式的呈现顺序对应的优先级相同,但至少有两个例外:这里(第二项可以是 any i> 表达式),并且在某些情况下涉及 C 样式转换和前缀运算符。
  • @JamesKanze 如果一种几乎是 C++ 但不完全的语言使用优先级并使用它来解决语法中的歧义,这不是行为会有所不同的示例,因为表达式a ? b, c : d 一开始就不会模棱两可。
  • @hvd 如果 C++ 使用优先级定义,a ? b : c, d 将分组 a ? b : (c, d)a ? b , c : d 将是非法的。
【解决方案2】:

是的,条件表达式的相关语法是:

logical-or-expression ? expression : assignment-expression

对于赋值表达式(也可以是条件表达式抛出表达式):

logical-or-expression assignment-operator assignment-expression

对于带有逗号运算符的表达式(assignment-expression 也可以是 表达式):

expression , assignment-expression

这意味着构造 a ? b : c, d 不能被解析为等同于 a ? b : (c, d),因为 c, d 不是 赋值表达式,但必须被解析为等同于 (a ? b : c), d。 p>

condition ? ia=1,ib=2,ic=3 : ia=21, ib=22, ic=23; 中没有未定义的行为,因为 condition 的计算在 ?: 的第二个或第三个操作数的计算之前排序,并且在每个包含逗号运算符的子表达式中,第一个操作数的计算逗号运算符的顺序在第二个操作数的计算之前排序。

【讨论】:

  • 非常感谢,也许我需要一些关于表达式和赋值表达式的东西。
【解决方案3】:

这是合法的,但是 stupid 这样写代码不是很有用。

代码

condition?ia=1, ib=2, ic=3:ia=21, ib=22, ic=23;

等价于

condition?(ia=1, ib=2, ic=3):ia=21;
ib=22;
ic=23;

只是更难阅读。

【讨论】:

  • 另一个问题?这里的逗号是如何解析的?或者逗号是怎么用的?
  • 逗号运算符可用于分隔表达式,就像这里一样。与终止表达式的分号不同,逗号允许您在一个地方有多个表达式,否则只能允许一个。在实践中不是很有用,并且可能会给读者造成混淆。
【解决方案4】:

问题是逗号运算符有the lowest precedence there is。多亏了这一点,条件运算符的else 部分只是第一个赋值,之后逗号运算符开始执行,其他两个语句也将执行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-23
    • 2017-11-01
    • 2011-03-08
    • 2014-08-05
    • 2018-06-10
    • 1970-01-01
    相关资源
    最近更新 更多