一 寫在開頭 1.1 本文內容 C語言是一門古老而又高深莫測的編程語言,她身上總是閃爍著各種“巨坑”(對於我這種沒參透的菜鳥而言)。實踐出真知,親們在看C語言的資料時可千萬別想當然啊。 二 開始裝13 這是某本關於C語言指針的書中的一個小部分,具體書名不說了,內容如下圖所示。 我於是寫了一段代碼進行 ...
一 寫在開頭
1.1 本文內容
C語言是一門古老而又高深莫測的編程語言,她身上總是閃爍著各種“巨坑”(對於我這種沒參透的菜鳥而言)。實踐出真知,親們在看C語言的資料時可千萬別想當然啊。
二 開始裝13
這是某本關於C語言指針的書中的一個小部分,具體書名不說了,內容如下圖所示。
我於是寫了一段代碼進行驗證,代碼如下所示。使用gcc -Wall temp.c進行編譯。WHAT?gcc沒有給出任何報錯,順利生成了a.out文件!難道是沒加-ansi選項的緣故,於是加上了-ansi選項重新編譯。見鬼了,仍然是沒有任何錯誤或警告出現!執行a.out,結果如下圖所示。
1 /* temp.c */ 2 #include <stdio.h> 3 4 int main() 5 { 6 int num = 5; 7 void *pv = # 8 9 printf("sizeof(void *) = %lu\n", sizeof(void *)); 10 printf("pv = %p\n", pv); 11 pv = pv + 1; 12 printf("pv = %p\n", pv); 13 14 return 0; 15 }
稍微解釋一下上面的程式。上面的程式之所以使用%lu作為printf的占位符,是因為在64位的ubuntu上,gcc提供的size_t其實是long unsigned int而非unsigned int。
從上面的執行結果來看,void *型指針變數的大小為8個位元組,這情有可原,因為這是64位機器。但pv指針在執行pv = pv + 1操作之後,其值並沒有按照書中說的那樣加8,而只是加1了!(書中假定void *型指針變數大小為4個位元組)
通過上述實踐,收穫的教訓有:
1. 實踐出真知,不要盡信書。尤其是面對C語言這種閃爍著“巨坑”光芒的編程語言!
2. 不要武斷地以為編譯器沒給error或warning的程式就是完美無瑕的程式!尤其是面對這種C標準的未定義行為的時候!想要寫好程式還得心中有譜。
3. 避免使用未定義行為!避免使用未定義行為!避免使用未定義行為!比如上述程式中的讓void *型指針加1的操作,這不僅無意義還有種作死的趕腳。
歡迎各位大佬批評指正,小菜我感激不盡!