2014-09-02 97 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遵循過程導向。並且()的關聯性從左到右。