→ stupid2:所以~平常在用的iostream.string...這些都是header???09/01 16:50
其實 iostream, string, cstdlib 這些東西
任何你寫在 #include <這裡> 的東西
都叫做 header file, 它們是實際存在你硬碟的檔案
因此你的硬碟裡,一定有個檔案叫做 iostream
(VS 2008 預設在 C:\Program Files\Microsoft Visual Studio 9.0\VC\include)
而 #include <iostream> 這個動作,其實就是
把 iostream 這個檔案的所有內容,一字不漏貼上,替換 #include <iostream> 這行
換句話說,如果你看 #include <iostream> 這行很不爽的話
可以從硬碟裡找出 iostream 這個檔案,整個複製貼上到你的程式碼裡,意義是一樣的
(不過好像比較累 XDD 。而且 iostream 很大,你的程式會變得超亂)
那幹嘛要把 iostream 貼到你的程式碼裡呢?
因為編譯器說:「你要用任何東西之前,要先讓我知道那是什麼東西」
譬如說如果你寫 cout << "Hello World"; 的話
C++ 一定要你交待清楚,cout 這個東西到底是什麼,不然它一定不會讓你過關
如果沒寫 #include <iostream> 而使用了 cout, 可能會看到類似的東西:
錯誤 1 error C2065: 'cout' : 未宣告的識別項
這行的意義就跟「'cout'是三小,我看不懂啦」差不多
因此答案就很清楚了,cout 這個東西是什麼,在 iostream 這個檔案裡有交待
你只要把 iostream 這個檔案「貼」(include)到你的程式碼前面,編譯就會過關。
但是故事還沒結束。
iostream 裡面,事實上只會交待「cout 長得什麼樣子」
而不會有「cout 的內部程式碼」,因此程式仍然無法執行
(不相信的話可以去看看,iostream 裡應該找不到 cout 內部真正做了什麼)
在你的程式碼編譯後,需要透過一個叫做「連結」的動作
這個動作會到你硬碟的某些特定目錄,找到 cout 內部程式碼所編譯出來的檔案
然後把這個檔案裡的程式碼(事實上是機器碼)跟你的程式結合在一起,變成可執行檔
上面那段用講的很玄,畫成圖就是這樣:
(合格的計概課本都會有類似的圖 XD)
白色:動作 紫色:檔案 黃色:說明箭頭指的那個檔案
iostream←這是compiler會附給你的檔案
│include
↓ 你做的編譯
你的 helloworld.cpp ────→ helloworld.obj ────→ helloworld.exe
↑這是你寫的程式 ↑↑這檔案叫object file ↑最後可執行的檔案
│連結
compiler提供的 早就做好的編譯 │
cout程式碼 ──────→ 內含有cout程式碼的library
↑你不一定會有這個檔案 ↑你一定會有這個檔案,它也是object file
唔,我應該再把這張簡陋的圖說清楚一點,但是有點懶了 XD
有問題可以再發問,或者請參考《深入淺出hello world》《程式設計師的基本素養》等
--
硬是不提那個 library 的檔名,是因為我不想把 DLL 拉進來...XD
還有,我怎麼老是在回答這種問題...XD
include相關說明,也可以另外參考:#1C7ImQKI (C_and_CPP)
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.117.171.46
推 loveme00835:推精美圖解 XD 09/01 19:23
推 hilorrk:好人超你是個超好人 09/01 20:23
推 zerodevil:小吐槽一下: 其實iostream的實作幾乎都看得到XD 09/01 20:25
推 zerodevil:以前還沒有extern template的時代只能寫死在header裡 09/01 20:29
→ tinlans:這篇說的應該是指 cout 的內部程式碼。 09/01 20:32
→ tinlans:它的實作出現在 header 的機率很低才對。 09/01 20:33
→ tinlans:另外「還沒有 extern template 的時代」是指...? 09/01 20:33
→ hilorrk:extern template不是C++0x才加入標準的嗎? 09/01 20:35
推 zerodevil:vs2008我去翻了一下 最後是call sprintf(汗 09/01 20:35
→ loveme00835:應該是說分離式模型吧...> < 09/01 20:35
→ zerodevil:gcc偷跑 好像很早就有extern template了..@@ 09/01 20:36
→ hilorrk:是這樣說沒錯..XD 如果是說export...有等於沒有= =|| 09/01 20:38
推 zerodevil:不過為了向下相容 還是看得到code 09/01 20:38
→ tinlans:分離編譯模型是 export 吧,這東西我只知道 comeau c++ 有 09/01 20:48
→ tinlans:。而且 cin / cout 本身是具體的物件,用不到那種特性。 09/01 20:49
→ uranusjr:淺顯易懂, 好文!XD 09/01 20:49
→ loveme00835:嗯嗯, 剛剛看太快= = 09/01 20:49
→ tinlans:extern template 在 C++0x 指的是壓抑具現化。 09/01 20:49
→ tinlans:但是同樣的,cin/cout 其實只是個物件,也就是單純的變數 09/01 20:52
→ tinlans:。所以我不太清楚跟 extern template 的關聯性。 09/01 20:52
→ loveme00835:後來想想 function template 應該是呼叫時具現化吧 ? 09/01 20:52
推 zerodevil:to t大 我混亂了@@ 09/01 20:53
→ zerodevil:本來以為原po說的"cout的內部程式碼"指的是 09/01 20:53
→ zerodevil:ostream::operator<<(blah)的實作 這不需要link額外的 09/01 20:54
→ loveme00835:應該還是要實作碼, extern 的功能... 09/01 20:54
→ zerodevil:library就能用吧? (當然更底層的io還是需要) 09/01 20:54
→ tinlans:operator<< 不用,我指的是 cin/cout 初始化的動作。 09/01 21:01
→ tinlans:libstdc++ 的 ios_init.cc 裡面的那些東西。 09/01 21:02
→ tinlans:function template 雖然是在呼叫點具現化,但它會變成所謂 09/01 21:02
→ tinlans:的 weak symbol,所以實際上不是那麼需要 extern。 09/01 21:03
→ tinlans:只是有了 extern template 的話可以精確控制具現點。 09/01 21:04
→ tinlans:然後也不必用到 weak symbol 的特性讓 linker 去挑。 09/01 21:04
→ tinlans:加上我記得 C++ 沒規定要怎麼實現,說不定有些 compiler 09/01 21:07
→ tinlans:會用 local symbol,這樣每個 object file 會有一份獨立 09/01 21:07
→ tinlans:具現體,最後的執行檔可能會很大。 09/01 21:07
其實沒想到我用 cout 這個例子會引起這麼大的討論
我只是想要舉一個「初學者一定用過的東西」當作例子來說明...XDD
也簡化了很多,譬如我就沒考慮 template, inline 這些因素
真的要認真討論的話,現在哪有人還在用 static linking... XDD
推 VictorTom:推:) 09/01 21:41
推 stupid2:努力消化中~~有種消化不良的感覺~ㄎㄎ 09/01 23:27
推 loveme00835:消化不良是正常的, 這需要瀏覽過不少本相關書籍才看得 09/01 23:32
→ loveme00835:懂 09/01 23:32
我一直很努力的想寫出很好懂的文耶
期待有一天能夠出版《笨蛋都能學會的C語言》或《笨蛋都能理解的作業系統》之類的書
看來還有努力的空間啊....(笑)
※ 編輯: james732 來自: 140.117.171.46 (09/02 00:00)
推 loveme00835:我是指推文啦! j 大不要傷心~ 拍拍 > < 09/02 00:04
→ james732:哈哈,開開玩笑~~XDD 09/02 00:17
推 jehovah:大推 果然深入淺出 09/02 08:45
推 nowar100:寫得很淺顯易懂阿 (Y) 09/02 08:48
推 tocute:好文!! 如果能把 lib 跟 dll 加進去那就更棒了!! 09/02 09:14
推 darkgerm:大推啊~~好期待你的書能趕快出版~~ 09/02 13:50
推 BlazarArc:好文!! 如果出書我就買 XD 09/02 14:37