Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
深入探討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++) 
 

More Related Content

深入探討 C 語言