看板 C_and_CPP 關於我們 聯絡資訊
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