1. 程式人生 > >Stay Hungry,Stay Foolish!!!

Stay Hungry,Stay Foolish!!!

C語言盲點

1.函式引數的求值順序依賴於編譯器,例如f(a,a++);是先求a++還是求a不一定
2.C語言中的大多數運算子對其運算元的求值順序也依賴於編譯器

警告

int i = f() * g();這裡先求f()還是先求g()不一定,所以不能寫出要先實現f(),在實現g()的函式;

程式中的順序點

定義:

指程式執行過程中修改變數值的最晚時刻。

有哪些順序點

1.每個完整表示式結束後,即分號後面
2.&&,||,三木運算子(?:),以及逗號表示式的每一個運算物件計算之後
3.函式呼叫中對所有實際引數的求值完成之後(進入函式體之前)

考慮以下程式碼輸出值

#include <stdio.h>
#include <stdlib.h> 
int main(int argc, char *argv[])
{
    int k = 2;
    int a = 1;
    k = k++ + k++;
    printf("k = %d\n",k);

    if(a--&&a)
    {
        printf("a = %d\n",a);
    }
    system("PAUSE");
    return 0;
}

分析:
1.k = k++ + k++;的順序點在‘ ; ’後,所以k++到真正去修改記憶體值是在分號後面,所以編譯器的行為是先k =2+2;之後k自增兩次

2.在遇到&&時候,每一個運算物件之後就是一個順序點所以a–執行後就是一個順序點,所以這是就去記憶體修改了a的值,所以就是if(1&&0)所以不執行printf

再考慮以下程式碼

#include <stdio.h>
#include <stdlib.h> 
int f(int i, int j)
{
    printf("%d, %d\n", i, j);
}

int main(int argc, char *argv[])
{
    int k = 1;

    f(k, k++);

    printf("%d\n"
, k); system("PAUSE"); return 0; } 輸出結果 //21 //2

也就是 i =2,j = 1, k = 2
之前提到實參在傳入函式之前對實參的求值完成之後是一個順序點,也就是在進行值傳遞的時候K已經是2了,