簡體   English   中英

C增量運算符

[英]C Increment operators

我已經在代碼塊中編譯了以下代碼,它顯示了輸出0 ... 0。 但是我認為它的輸出應該為0 ... 1,因為“ if”語句在此處不正確,因此不會執行“ if”之后的語句。然后j增加1(因為“ if”語句中的j ++),但是我仍然為0。因此,最后一個printf()應該為0 ... 1。

#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;
}

由於i0 (虛假),因此沒有理由執行j++ 這就是所謂的短路。

if(a < v.size() && v[a] == 5) // do something類的檢查中很有用if(a < v.size() && v[a] == 5) // do something

參見C11 6.5.13邏輯AND運算符p4 (我強調)

與按位二進制&運算符不同,&&運算符保證從左到右的求值; 如果對第二個操作數求值,則在第一個和第二個操作數的求值之間會有一個序列點。 如果第一個操作數比較等於0,則不計算第二個操作數。

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

條件( i )的第一部分已經為false,因此第二部分( j++ )未執行。

您不會增加j 查看您的if語句:

if(i && j++)

僅當ij均為true時,才執行if塊。 但是由於i已經是虛假的,所以甚至不需要檢查j++ 也稱為短路評估

如果沒有應用if條件,則遞增到j的原因是因為該表達式正在短路-即,i永遠不會為非零,因此不需要評估第二個表達式。

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

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

或如果不是:

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

由於第一個條件i&&運算符的左側)的求值已經返回false,因此未執行j++表達式,因此,第二個條件j++不會求值。

這是編譯器進行的常見優化,通常稱為短路條件評估 ,在某些編譯器中,您可以關閉此優化,以避免這種副作用。

如您在此示例代碼中所看到的,從您的源中未執行第二個IF:

    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

如其他答案所述。

如您所述,if語句為false則為true。 但是我相信所使用的概念/邏輯是不合適的,原因將隨之而來。

在此之前,讓我們了解&&(Logical AND)運算符的工作原理。 如果聲明與之關聯的兩個操作數均為true,則僅結果為true。 注意:1.對於編譯器,這意味着如果任何一個操作數為假,則編譯器將不會進一步計算,即跳至下一有效代碼行。 2. 0(零)狀態為false-在編程中。

好吧,編譯器首先搜索運算符,然后查找與其關聯的操作數。

因此,一旦編譯器遇到'&&',它就會從運算符的左側開始,因為&&(邏輯AND)的關聯性從左到右,並評估左側操作數的值為0(零)。 現在,請參閱注釋2,然后是1。

因此,編譯器跳到下一個有效的語句printf(“%d ...%d”,i,j);

此處,未對變量“ j”進行增量,因此“ j”的值將保持為0(零)。

注意:為了進一步弄清這個想法,我建議嘗試使用相同的示例使用不同的i和j值,例如i = 1和j = 1或i = 2和j = 1。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM