不簡單的hello world之C標準庫(第二部分)

目錄java


1. 庫(Library)的定義linux

2. 爲何須要庫程序員

3. 庫是如何生成windows

4. 庫裏面有什麼微信

5. 庫的分類app

6. 如何建立庫函數

7. 什麼是標準庫spa

8. 標準庫的優勢操作系統



這是承接上一篇文章《不簡單的hello world值C標準庫第一部分》。咱們繼續該主題的內容。.net


4. 庫裏面有什麼


咱們在上一節當中介紹了庫是如何生成的,那麼庫裏面有什麼呢,關於這個問題可能有的同窗會問了,你不是說了嗎,裏面不就是包含了咱們寫的程序的二進制CPU能夠讀懂的形式嗎,親愛的同窗們,在上一節中主要是來說述庫如何生成的,因此這樣說是爲了爲了讓你們更容易的理解上一節,真實的狀況是庫裏面不只僅是包含了二進制指令,僅僅是指令是不夠的,還須要的一項是什麼呢,有的同窗可能已經猜到了,那就是數據,關於庫裏面有什麼一樣不是能在這一小節中能完整描述的,我會在後面的文章給你們詳細講解,庫裏面到底有什麼。敬請期待。


5. 庫的分類


和任何東西同樣,庫也是有分類的。不用擔憂,庫的分類很簡單,就只有兩種,動態庫(Dynamic Library)和靜態連接庫(Static library)。

在Windows世界中,動態連接庫就是大名鼎鼎的.dll結尾的文件,靜態庫是以.lib結尾的文件。

在Linux世界中,動態連接庫是以.so結尾的文件,而靜態庫是以.a結尾的文件。

好比在Linux中,你有一個用來進行數學計算的庫math,那麼生成的動態庫的名字就是libmath.so, 而對應的靜態庫的名字叫作libmath.a。以下圖因此:


靜態庫



如圖所示,這裏但願強調的一點就是,一樣的一份代碼,咱們便可以使用連接器(Linker)生成動態連接庫,也能夠生成靜態連接庫,至因而如何生成的,這兩種庫實現上有什麼差異,一樣的我會在下一篇文章當中給你們詳細講解。

可能又有同窗繼續問了,爲何這麼麻煩的有兩種庫呢,又是動態連接庫又是靜態連接庫的,這是很重要的一個問題,一樣不適合在這裏簡單的描述描述,和以前的作法同樣,我會在接下來的文章當中給你們詳細講解,由於我想系統性的給你們講解計算機基礎性的內容,好多相關的內容尚未寫完,由於尚未寫完因此具體調到哪個章節暫時還不能肯定,因此還但願同窗們辛苦一點,都寫完後在有這樣的狀況就能夠直接告訴同窗們調到那一章節直接看就行了(這裏留下的問題會在下一個主題連接器中給你們詳解介紹)。

6. 如何建立庫


如何建立庫?這一節和「庫是如何生成的」不同嗎,是的,的確不同,由於我也想不出一個很能直接表達清楚的標題,因此在這裏特此解釋一下,在「庫是如何生成的」這一節當中,咱們主要是引出連接器(Linker)這一重量級嘉賓,講述庫是由連接器來生成的,主角是連接器(Linker), 而這一節的主角是各位讀這篇文章的同窗們,主要是來說咱們如何指揮連接器(Linker)來生成咱們須要的庫。

原本想在這裏給你們詳細講解一下的,可是考慮到這篇文章的主要內容是將庫的,而如何建立動態庫靜態庫和連接器緊密相關,由於這一部分的內容一樣也在下一篇文章當中給你們詳細講解。

7. 什麼是標準庫


在前幾節當中咱們詳細講解了,什麼是庫,庫是如何生成的以及庫的分類和建立等,如今讓咱們回到文章最開始的內容,講解一下標準庫,下面我用一個例子來給你們形象的描述一下庫以及標準庫。

互聯網的誕生讓咱們真正的見識到了高手在民間,因此神醫也每每在民間,假如你是古代的皇帝想造福一方百姓,因此你派人找遍散落在民間的神醫寫就的藥方,收集到這些藥方後整理彙總成了一本書叫作《神醫那些事》,這本書拯救了無數人的生命,載入史冊造福至今。

在這個例子當中,民間神醫高手寫就的方子就相似於咱們平時使用的各類函數,好比printf,把各類這樣的函數聚集起來就叫作庫(library),就比如《神醫那些事》這本書,這本書裏記載了針對各類疾病的明方,而庫中也就是有各類函數的實現,因此你如今應該明白了所謂的庫是什麼了吧,無非就是裏面包含了你可能用到的各類函數而已,而這些函數若是咱們本身實現那不管是健壯性仍是可維護性等都不如高手寫好的函數,因此咱們只需用就能夠了。

那什麼又是標準庫呢,仍是用上面的例子,假如明見的神醫高手們對同一種疾病的描述很不同(相似函數描述),因此做爲皇帝的你大手一揮,既然描述各不同咱們就定義一個標準吧,對於一種疾病都有一個官方的描述,你們都以此爲標準,而《神醫那些事》這本書就是依據你制定的標準來寫的,因此就比如標準庫了。

8. 標準庫的優勢


有了標準庫,其中一個很大的優勢就是程序的可移植性,一樣的hellworld程序,你在linux平臺上能夠跑起來,並且不加修改也能夠在vs上跑起來,windows和linux這兩個操做系統的實現方式徹底不同,可是這個helloworld能夠在兩個平臺上不加修改的運行,這裏就應該歸功於標準庫。是標準庫屏蔽了底層操做系統的細節。程序員只須要調用標準庫裏的函數,標準庫保證這些函數不管是在哪一個平臺均可以運行,怎麼樣是否是有種熟悉的味道,聰明的讀者應該想到運行Java的JVM,Java之因此能跨平臺運行不是Java代碼自己而是由於運行Java的JVM能夠在多個平臺上運行(這裏應該有兩張圖,做爲對比),至於相似於java這樣的語言究竟是如何被類JVM的解釋器運行起來的,我會在後面的章節中給你們詳細介紹,對這個問題感興趣的同窗不要錯過哦(獲取這篇文章,請關注個人公共帳號"碼農的荒島求生")。

上面提到的這種方法這是計算機科學當中經常使用的一種解決問題的方法,那就是增長一層來屏蔽底層差別。這裏引用David Wheeler的一句名言:

All problems in computer science can be solved by another level of indirection.


計算機科學當中的任何問題均可以經過增長一層抽象層來解決。

關於Java的一次編譯處處運行如圖所示:

之因此Java是跨平臺的,是由於不一樣平臺上的JVM(如上圖所示的JVM for x86 for Windows, JVM for Linux等)對Java代碼的解釋執行是一致的(可能有的同窗不明白到底什麼是解釋執行,不用着急,我會在後面的文章當中不但給你們講解清楚什麼是解釋執行,並且會給你們講清楚是一些程序好比Java是如何解釋執行的,歡迎你們關注個人公共帳號: 碼農的荒島求生),只要相應的平臺上有JVM,你寫的Java程序就能夠不加修改在該平臺上執行。你能夠把標準庫想象成這裏的JVM,固然這個類比不太恰當,緣由在於Java程序是被JVM解釋執行的,而咱們寫的C程序是依賴於標準庫中的函數,C程序和標準庫的地位是同樣的,而Java程序是JVM的輸入。可是經過這個類比你應該能明白標準庫所起到做用了。


咱們在helloworld中使用的printf函數正是在標準庫中實現的。


如今你應該明白printf在哪裏實現的了吧。咱們平時使用malloc,strcpy等等都是在標準庫中實現的,你也許會問若是要分配內存咱們必定要使用malloc嗎,固然不是這樣的,咱們在前面也講解了,標準庫中的各類函數也是普通的代碼,若是你以爲分配內存用malloc不夠酷的話你徹底能夠實現本身的malloc函數,你也許又會問了,malloc是怎麼實現的呢,神奇的malloc是如何給咱們的代碼分配內存的呢,不要着急,我會在後面的內容中給你們講解。之因此舉這個例子就是想強調一點,標準庫中函數也是普普統統的c程序,你們不要以爲標準庫中的函數有什麼的特別之處,沒有什麼特別之處,若是你喜歡的話你徹底能夠本身來實現一套標準庫中的函數,可是一般狀況下咱們不會本身來實現這些煩人的細節的,標準庫幫咱們處理的很好了,大部分狀況下只須要用標準庫中的就能夠了,固然在一些要求比較高的狀況下是須要實現本身的函數的,好比上面舉例用的malloc函數,Google就以爲標準庫中的malloc實現的不是很好,本身用起來不是很順手,因此Google就本身實現了一套內存分配方法,這些會在後面給你們講解。

OK,讓咱們總結一下,

一般狀況下,咱們的程序須要依賴標準庫提供的函數來幫助咱們完成任務,如圖所示:


可是也要記住標準庫中的函數也是普普統統的c程序並無什麼神祕之處,你徹底能夠實現本身的標準庫函數。


今天給你們講解了冰山的一角,C標準庫,你看明白了嗎,咱們在上一節中留下了一個問題,那就是咱們沒有告訴編譯器頭文件(好比stdio.h)在哪裏,這個咱們咱們沒有在這一節中回答,爲了給同窗們更多思考的問題,這裏這裏再給你們一個思考題,就是咱們也沒有告訴編譯器的實現文件在哪裏,編譯器是如何找到的呢,咱們講解的標準庫到底在哪裏呢? 我會在下一篇文章當中給你們詳細講解。


本文分享自微信公衆號 - 碼農的荒島求生(escape-it)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索