2012-04-13 101 views
35

通常,'?'操作者在下面的形式使用:具有空的第二参数的C条件运算符('?')

A ? B : C 

然而,在其中B = A I所看到的下列缩写

A ? : C 

这令人惊讶地工作的情况。 (风格明智的)留下第二个参数会更好吗?或者某些编译器无法处理这个问题?

+0

看起来像[Groovy](http://en.wikipedia.org/wiki/Groovy_%28programming_language%29)类似的语法。 – Lion 2012-04-13 15:24:34

回答

32

语言C不允许使用(据我所知),但编译器如gcc的快捷键为?:c为extensiona?:c的含义与a?a:c相同。

+18

这意味着...与'a'不包含副作用的警告一样。 'a?:c'只执行一次'a',而'a?a:c'则执行两次'a'的副作用。 – 2012-04-13 21:05:21

3

除非我犯了严重的错误,否则您使用的是编译器扩展(猜测,gcc)。我很确定标准而不是允许您省略三元运算符的第二个操作数。

16

它是一个gcc的扩展

Conditionals with Omitted Operands

x ? : y相当于x ? x : y

+2

您链接的页面与自身矛盾。一方面它说:“这个例子完全等价于'x?x:y'”,这意味着'x'被计算两次,但另一方面最后一段声明'x'只被计算一次,这将使它完全等价于'x || y',而不是'x? x:y' – Celada 2012-04-13 15:03:21

+1

@Celada:我想这意味着要说'x? :y'大致** ​​*相当于'x? x:y'除了'x'只在前一种情况下评估一次。 – 2012-04-13 15:05:53

+3

@Celada:'x || y'评估为0或1,而这个算子不是这种情况。 – 2012-04-13 15:07:13

0

最好是离开的第二个参数英寸。如果B都没有改变,你可能不记得修改上面的语句。此外,如果您将B从声明中删除,其他人可能难以阅读代码并改进它。

1

我做了一些研究网络,acording维基百科,这种行为是由GNU扩展C. http://en.wikipedia.org/wiki/%3F:#C

的支持所以这是非常有可能的是其他编译器认为这是非法的。顺便说一句,这个操作符被称为三元条件,所以你可以浏览它。

编辑:

我在gcc和苹果LLVM检查,它工作正常。

3

我填写了一下。

该标准使用术语有条件的运算符

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

一个条件表达式不会产生一个左值。另外; Wikipedia; Conditional

注:即:C++有:
       逻辑OR-表达?表情:分配 -expression

Constraints: 
* The first operand shall have scalar type[1]. 
* One of the following shall hold for the second and third operands: 
    — both operands have arithmetic type[2]; 
    — both operands have the same structure[3] or union type[4]; 
    — both operands have void type[5]; 
    — both operands are pointers to qualified or unqualified[6] versions of compatible 
    types[7]; 
    — one operand is a pointer and the other is a null pointer constant[8]; or 
    — one operand is a pointer to an object or incomplete type[9] and the other 
    is a pointer to a qualified or unqualified version of void. 

足食物:

[1] Scalar type  : Arithmetic types and pointer types. 
[2] Arithmetic type : Integer and floating types. 
[3] Structure type : A sequentially allocated nonempty set of member objects (and, in 
        certain circumstances, an incomplete array), each of which has an 
        optionally specified name and possibly distinct type. 
[4] Union type  : An overlapping nonempty set of member objects, each of which has 
        an optionally specified name and possibly distinct type. 
[5] Void type  : An empty set of values; it is an incomplete type that cannot be 
        completed. 
[6] Qualified type : 1998 (const and volatile), 1999 (restrict), respectively 
        2011 (_Atomic). * 
[7] Compatible type : Their types are the same. 
[8] Null ptr. const.: NULL; implementation-defined null pointer constant. 
[9] Incomplete type : Types that describe objects but lack information needed to determine 
         their sizes. 

*Type qualifiers in C

所以:不明智的使用。