我在某处读到C中的?:
运算符在C ++中略有不同,有些源代码在两种语言中都有不同的作用。不幸的是,我找不到任何地方的文字。有谁知道这个区别是什么?
答案 0 :(得分:69)
C ++中的条件运算符可以返回左值,而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));
答案 1 :(得分:22)
主要的实际区别在于,在C中,?:的评估永远不会产生l值,就像在C ++中一样。
其定义存在其他差异,几乎没有实际后果。在C ++中,第一个操作数转换为bool,在C中将其与0进行比较。这与C和C ++之间==,!=等定义的差异是一致的。
在C ++中还有更复杂的规则,用于根据第二和第三个操作数的类型推导出一个?:表达式的类型。这反映了在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时生成错误:“错误:赋值中的无效左值”,但编译为C ++时代码编译时没有错误。
修改强> 虽然?:不能在C中返回l值,但令人惊讶的是?:的语法是:
conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression
这意味着a ? b : c = d
解析为(a ? b : c) = d
,即使(由于“不是l值”规则),这也不会产生有效的表达式。
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;