代码之家  ›  专栏  ›  技术社区  ›  rlbond

C与C++条件算子的差异

  •  46
  • rlbond  · 技术社区  · 15 年前

    我在某个地方读到 ?:

    2 回复  |  直到 15 年前
        1
  •  74
  •   goldPseudo    7 年前

    C++中的条件运算符可以返回一个LValk,而C不允许类似的功能。因此,以下内容在C++中是合法的:

    (true ? a : b) = 1;
    

    要在C中复制这一点,您必须求助于if/else,或者直接处理引用:

    *(true ? &a : &b) = 1;
    

    也在C++中, ?: = 运营商有 equal precedence and group right-to-left ,以便:

    (true ? a = 1 : b = 2);
    

    是有效的C++代码,但是在C中没有在最后表达式周围插入圆括号时会出现错误:

    (true ? a = 1 : (b = 2));
    
        2
  •  24
  •   CB Bailey    15 年前

    它的定义还有其他不同之处,几乎没有实际后果。在C++中,第一个操作数被转换成布尔值,在C中,它与0比较。这与==,!=,的定义不同,在C和C++之间。

    C++中还存在更复杂的规则,用于根据第二和第三操作数的类型推断A:表达式的类型。这反映了C++中用户定义隐式转换的可能性。

    示例代码。有效C++;无效的C。

    extern int h(int p, int q);
    
    int g(int x)
    {
            int a = 3, b = 5;
    
            (x ? a : b) = 7;
    
            return h( a, b );
    }
    

    gcc 当编译为C时,会产生错误:“错误:赋值中的无效LValk”,但是编译为C++时,代码编译时无错误。

    编辑: 虽然?:无法在C中返回l值,但?:的语法可能是:

    conditional-expression:
        logical-OR-expression
        logical-OR-expression ? expression : conditional-expression
    

    这意味着 a ? b : c = d 解析为 (a ? b : c) = d

    C++将语法改变为:

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

    而允许条件表达式在某些情况下成为l值的扩展可能会 A.b:c=d a ? b : (c = d) .

    虽然我没有任何证据,但我的假设是,由于语法更改不会破坏与现有C代码的兼容性,因此新语法很可能不会对以下表达式产生太多惊喜:

    make_zero ? z = 0 : z = 1;