2014-09-02 65 views
6
main() 

{ 

     int a=10,b=30,c=0; 

     if(c =({a+b;b-a;})) 
     { 
      printf("%d",c); 
     } 

} 

为什么构造({;})在C中是合法的,为什么它返回最后一个语句值作为表达式的结果它的工作类似于逗号运算符)?变量1 =({语句1;语句2;})在C中构造

+0

看起来像是在ANSI C中由parens表达式包围的[Compund语句(块)]的复制(http:// stackoverflow。com/questions/1238016/are-compund-statements-blocks-surrounded-by-parens-expressions-in-ansi-c) – 2014-09-02 09:40:27

回答

15

这不是合法的标准C99,但它是一个非常有用的GCC扩展,被称为statement-exprs(括号括起来的复合语句以某种表达式结尾)。

IIRC,一些其他编译器支持该扩展,例如, Clang/LLVM

语句表达式是有用得多,当它们包含控制流的变化和副作用,如:

c = 2*({while (a>0) a--,b--; a+b;}); 

然而,在特定情况下,你可以只使用comma operator

if (c=(a+b,b-a)) 

由于a+b没有任何副作用,我想优化编译器可以处理它,如

if (c=b-a) 

GCC提供了其他有用extensions,特别是local labels使用__label__label as values与计算转移(在threaded interpreters非常有用的...)。我不清楚他们为什么没有被标准化。我希望他们会。

+0

'goto'已经够糟糕了,我们不想通过允许它来鼓励它与可变目的地一起使用! – 2014-09-02 05:25:19

+1

有时计算出的goto非常有用(例如,在一个线程字节码解释器中)。某些代码(例如Ocaml编译器的文件“byterun/interp.c”)的字节码解释器在使用计算得到的goto时运行速度提高了30%。 – 2014-09-02 05:30:43

+1

knowledge ++,Thanks !! ... – 2014-09-02 06:40:13

1
main() 
    { 

    int a=10,b=30,c=0; 

    if(c =({a+b;b-a;})) 
    { 
     printf("%d",c); 
    } 

    } 

这里,{a+b;b-a;}是一个scope.In你写了2个statements.This这实际上是为

{ 
    c=a+b; 
    c=b-a; 
    } 

最初C值,因为a+b治疗是40。再次,c被b-a修改。为了证明这一点,考虑以下三种情况。

(1)。这里o/p是c = 40和a = 40;因为在范围末尾(即)在last语句中是dummy(;)。 so,c=a+b是o/p。 (2)

if(c=({(a=a+b);b-a;})) 
    { 
     printf("%d\n",c); 
     printf("%d\n",a); 
    } 

这里o/p是c = -10,a = 40。因为最后的陈述是b-a。这个值被分配给c。 (3)主() {

int a=10,b=30,c=0; 
    if(c=({(a=a+b);0;})) 
     { 
     printf("%d\n",c); 
     printf("%d\n",a); 
     } 
    printf("%d\n",c); 
    } 

这里O/P为c = 0 only.If不执行由于最后一个语句的,为0;

C遵循过程导向。并且()的关联性从左到右。