2013-07-16 95 views
0

我已經在代碼塊中編譯了下面的代碼,它顯示了輸出0 ... 0。但我認爲它的輸出應該是0 ... 1,因爲「if」語句在這裏不是真的,所以跟在「if」後面的語句沒有被執行。然後j增加1(因爲「if」語句中的j ++),但是我仍然是0.所以,最後一個printf()應該給0 ... 1。C增量運算符

#include <stdio.h> 

int main() 
{ 
    int i =0,j=0; 
    if(i && j++) 
     printf("%d..%d\n",i++,j); 
    printf("%d...%d",i,j); 
    return 0; 
} 

回答

3

C11 6.5.13邏輯與運算符P4(我的重點)

不同的是按位二進制&運算符,& &運營商保證 左到右的評價;如果評估第二個操作數,則在第一個和第二個操作數的評估之間存在一個序列點。 如果第一個操作數比較等於0,則不計算第二個操作數 。

您示例中的第一個操作數是i。它比較等於0,所以第二個操作數(j++)不被評估(執行)。因此,正確的,你以後的printf表明j仍爲0

+0

+1對於標準參考 – RiaD

0

條件(i)的第一部分是已經假所以不執行所述第二部分(j++)。

3

由於i0(falsy),因此沒有理由執行j++。這叫做短路。

這是非常有用的檢查,像if(a < v.size() && v[a] == 5) // do something

0

你不會得到遞增j。看看你的if語句:

if(i && j++) 

你只執行,如果塊當兩個ij是真實的。但由於i已經是假的,所以不需要檢查j++。它也被稱爲Short-circuit evaluation

0

在if條件下j的增量未被應用的原因是因爲該表達式被短路 - 即,i從不爲非零,所以不需要評估第二個表達式。

0

而不是使用邏輯和&&,使用按位與&的,不會短路和工作,你想,只要ij01方式:

... 
if(i & j++) 
    printf("%d..%d\n",i++,j); 

,或者如果他們又不是:

if (!!i & !!(j++)) 
    ... 
0

不執行j++表達式,因爲第一個條件i(該&&運營商的左側)的評估已經返回false,這樣,第二個條件j++沒有評估。

這是編譯器做出的常見優化,通常稱爲短路條件評估,在一些編譯器中可以關掉這個優化,以避免這種副作用。

0

如您在本示例代碼中看到,從源 第二如果不執行:

movl i(%rip), %eax  
    testl %eax, %eax   ; <-- if i 
    je .L2 
    movl j(%rip), %eax 
    testl %eax, %eax   ; <-- if j Not EXECUTED !!! 
    setne %dl 
    addl $1, %eax   ; <-- j++ 
    movl %eax, j(%rip) 
    testb %dl, %dl 
    je .L2 
    ...       ; inner IF 
.j2 

在對方的回答解釋。

0

正如你所說,如果陳述是錯誤的是真的。 但我相信所用的概念/邏輯是不恰當的,原因會隨之而來。

之前,讓我們瞭解& &(邏輯與)運算符的工作。 如果聲明如果與它相關的兩個操作數都爲真,則只有結果爲真。 注意:1.對於編譯器來說,它意味着如果任何一個操作數是假的,編譯器將不會進一步計算,即跳到下一個有效的代碼行。 2. 0(零)狀態爲false - 編程中。

那麼, 編譯器在第一次搜索操作符,然後查找與它相關聯的操作數 。

所以,只要編譯器遇到「& &」這將着眼於操作人員的左側 的關聯& &(邏輯與)是左到右和操作數評估值在左邊是0(零)。 現在,請參考備註2,然後是1.

因此,編譯器跳轉到下一個有效語句,即 printf(「%d ...%d」,i,j);

在這裏,沒有增量是可變「Ĵ製造」,因此價值‘J’將保持0(零)

注:要得到進一步的想法清楚,我建議嘗試與i和j的不同值相同的例子,如i = 1和j = 1或i = 2和j = 1