Stay Hungry,Stay Foolish!!!
阿新 • • 發佈:2019-01-31
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;
}
輸出結果
//2,1
//2
也就是 i =2,j = 1, k = 2
之前提到實參在傳入函式之前對實參的求值完成之後是一個順序點,也就是在進行值傳遞的時候K已經是2了,