深入探討 C 語言
-
Upload
pinglun-liao -
Category
Technology
-
view
46 -
download
0
Transcript of 深入探討 C 語言
深入探討C語言 假設你在面試求職者是否了解C語言,於是問了第一個問題: ================================================= 此程式碼會有什麼結果? ================================================= 底下是兩位求職者的回答, 假求職者: 「 需要加上#include <stdio.h>和 return 0,這樣才可通過編譯(compile)與連結(link),執行時會在螢幕上輸出42。 」 真求職者: 「 可能需要加上含有printf()宣告的 #include <stdio.h>,這樣才可通過編譯(compile)與連結(link),執行時會將數字42加上換行寫到標準輸出串流。 此程式碼會無法通過C++編譯器,因為C++語言需要宣告所有的函式。 然而C編譯器會建立隱藏的printf()函式宣告,並將此程式碼編譯成object file,與標準函式庫連結時,就會找到printf()函式的定義,於是上述程式碼就可編譯、連結與執行,但可能會看到一個警告。 在C99與C++98,程式離開值(exit value)定義為執行環境的成功回傳值,但舊版的C,例如ANSI C與 K&R,在此程式碼中,程式的離開值會成為未定義的垃圾值(garbage value)。此程式碼的離開值應該會是3,因為printf()會回傳3→為寫到標準輸出的字元個數。 提到C語言標準,那此程式碼的進入點要寫成int main(void),還有容許我吹毛求疵一下,C語言標準說程式碼需要以換行為結尾。 」 此程式碼的編譯與執行情況
第二個問題: ================================================= 此程式碼會有什麼結果? ================================================= 假求職者: 「 這未定義吧?會得到垃圾值(garbage value)? 」 真求職者: 「 不,會得到1、2、3。因為語言規格說靜態變數的初始值為0。 」 此程式碼的編譯與執行情況
第三個問題: ================================================= 此程式碼會有什麼結果? ================================================= 假求職者: 「 得到1、1、1。 」 真求職者: 「 會得到未定義的值,理論上會得到三個垃圾值,實際上自動變數(auto variables)被配置在執行堆疊裡,變數a可能會在相同的的記憶體位置,可能會得到三個連續值,但有最佳化的情況又不一樣了。 將自動變數的初始值設為0會增加函式呼叫的成本,C語言非常重視執行速度。另外在C++中,靜態變數的初始執不是0,而是設定為預設值,而基本型別剛好是0。 」 此程式碼的編譯與執行情況
第四個問題: ================================================= 此程式碼會有什麼結果? ================================================= 假求職者: 「 因為a是static,初始值會是零,於是會輸出1、2、3。 」 那此程式碼又會有什麼結果? 假求職者: 「 垃圾值、垃圾值、垃圾值。 初始值還是零嗎? 是不是跟私有(private)變數和公開(public)變數有關? 」 真求職者: 「
會輸出1、2、3,因為此變數的初始值也是零。然而跟static不同的是連結器(linker)的可見度,此變數可在其他的編譯單元存取到,但有加static的變數,就只能在此編譯單元可見。 」 第五個問題: ================================================= 請解釋會什麼執行結果會是42。 ================================================= 假求職者: 「 也許編譯器有存放變數的地方,在bar()中變數被建立了,而在foo()中會依變數a的記憶體位址去取值,如果將bar()與foo()中的變數名稱改為不一樣,結果應該就不會是42了。 」 真求職者: 「 真棒!我喜歡這題目。你要我解釋execution stack與activation frames嗎? (不用,但若是做最佳化或是使用別的編譯器又會是什麼情況?) 很多事都可能發生,不過結果不會是42。 」 剩下的請有興趣的人閱讀參考資料吧。
References: [1] Deep C (and C++)