站長資訊網(wǎng)
        最全最豐富的資訊網(wǎng)站

        h文件和c文件的關(guān)系是什么

        h文件經(jīng)常被放在.c(.cpp)文件的頭部,所以就給它起名叫做“頭文件”。h文件就是將.c文件重復(fù)的聲明語句提取出來,放在一個新文件里,然后在需要的.c(.cpp)文件中敲入“#include XXXX”這樣的語句即可的文件。

        h文件和c文件的關(guān)系是什么本教程操作環(huán)境:windows7系統(tǒng)、C++17版本、Dell G3電腦。

        詳解C語言項(xiàng)目中.h文件和.c文件的關(guān)系

        在編譯器只認(rèn)識.c(.cpp))文件,而不知道.h是何物的年代,那時的人們寫了很多的.c(.cpp)文件,漸漸地,人們發(fā)現(xiàn)在很多.c(.cpp)文件中的聲明語句就是相同的,但他們卻不得不一個字一個字地重復(fù)地將這些內(nèi)容敲入每個.c(.cpp)文件。但更為恐怖的是,當(dāng)其中一個聲明有變更時,就需要檢查所有的.c(.cpp)文件。

        于是人們將重復(fù)的部分提取出來,放在一個新文件里,然后在需要的.c(.cpp)文件中敲入#include XXXX這樣的語句。這樣即使某個聲明發(fā)生了變更,也再不需要到處尋找與修改了。因?yàn)檫@個新文件,經(jīng)常被放在.c(.cpp)文件的頭部,所以就給它起名叫做“頭文件”,擴(kuò)展名是.h。

        在我們語言的初學(xué)階段,往往我們的程序只有一個.c的文件或這很少的幾個,這時我們就很少遇到頭文件組織這個頭疼的問題,隨著我們程序的增加,代碼 量到了幾千行甚至幾萬行,文件數(shù)也越來越多。這時這些文件的組織就成了一個問題,其實(shí)說白了這些文件的組織問題從理論上來說是軟件工程中的模塊設(shè)計(jì)等等的問題。

        頭文件的作用的簡短描述:

        (1)通過頭文件來調(diào)用庫功能。在很多場合,源代碼不便(或不準(zhǔn))向用戶公布,只要向用戶提供頭文件和二進(jìn)制的庫即可。用戶只需要按照頭文件中的接口聲明來調(diào)用庫功能,而不必關(guān)心接口怎么實(shí)現(xiàn)的。編譯器會從庫中提取相應(yīng)的代碼。

        (2)頭文件能加強(qiáng)類型安全檢查。如果某個接口被實(shí)現(xiàn)或被使用時,其方式與頭文件中的聲明不一致,編譯器就會指出錯誤,這一簡單的規(guī)則能大大減輕程序員調(diào)試、改錯的負(fù)擔(dān)。

        比方說 我在aaa.h里定義了一個函數(shù)的聲明,然后我在aaa.h的同一個目錄下建立aaa.c , aaa.c里定義了這個函數(shù)的實(shí)現(xiàn),然后是在main函數(shù)所在.c文件里#include這個aaa.h 然后我就可以使用這個函數(shù)了。 main在運(yùn)行時就會找到這個定義了這個函數(shù)的aaa.c文件。這是因?yàn)椋簃ain函數(shù)為標(biāo)準(zhǔn)C/C++的程序入口,編譯器會先找到該函數(shù)所在的文件。

        假定編譯程序編譯myproj.c(其中含main())時,發(fā)現(xiàn)它include了mylib.h(其中聲明了函數(shù)void test()),那么此時編譯器將按照事先設(shè)定的路徑(Include路徑列表及代碼文件所在的路徑)查找與之同名的實(shí)現(xiàn)文件(擴(kuò)展名為.cpp或.c,此例中為mylib.c),如果找到該文件,并在其中找到該函數(shù)(此例中為void test())的實(shí)現(xiàn)代碼,則繼續(xù)編譯。

        如果在指定目錄找不到實(shí)現(xiàn)文件,或者在該文件及后續(xù)的各include文件中未找到實(shí)現(xiàn)代碼,則返回一個編譯錯誤.其實(shí)include的過程完全可以“看成”是一個文件拼接的過程,將聲明和實(shí)現(xiàn)分別寫在頭文件及C文件中,或者將二者同時寫在頭文件中,理論上沒有本質(zhì)的區(qū)別。

        理論上來說C文件與頭文件里的內(nèi)容,只要是C語言所支持的,無論寫什么都可以的,比如你在頭文件中寫函數(shù)體,只要在任何一個C文件包含此頭文件就可以將這個函數(shù)編譯成目標(biāo)文件的一部分(編譯是以C文件為單位的,如果不在任何C文件中包含此頭文件的話,這段代碼就形同虛設(shè)),你可以在C文件中進(jìn)行函數(shù)聲明,變量聲明,結(jié)構(gòu)體聲明,這也不成問題!!!那為何一定要分成頭文件與C文件呢?又為何一般都在頭件中進(jìn)行函數(shù),變量聲明,宏聲明,結(jié)構(gòu)體聲明呢?而在C文件中去進(jìn)行變量定義,函數(shù)實(shí)現(xiàn)呢??

        要理解C文件與頭文件有什么不同之處,首先需要弄明白編譯器的工作過程,一般說來編譯器會做以下幾個過程:

        1.預(yù)處理階段

        2.詞法與語法分析階段

        3.編譯階段,首先編譯成純匯編語句,再將之匯編成跟CPU相關(guān)的二進(jìn)制碼,生成各個目標(biāo)文件

        4.連接階段,將各個目標(biāo)文件中的各段代碼進(jìn)行絕對地址定位,生成跟特定平臺相關(guān)的可執(zhí)行文件,編譯器在編譯時是以C文件為單位進(jìn)行的,也就是說如果你的項(xiàng)目中一個C文件都沒有,那么你的項(xiàng)目將無法編譯,連接器是以目標(biāo)文件為單位,它將一個或多個目標(biāo)文件進(jìn)行函數(shù)與變量的重定位,生成最終的可執(zhí)行文件,在PC上的程序開發(fā),一般都有一個main函數(shù),這是各個編譯器的約定。為了生成一個最終的可執(zhí)行文件,就需要一些目標(biāo)文件,也就是需要C文件,而這些C文件中又需要一個main函數(shù)作為可執(zhí)行程序的入口。

        簡單些說就是C語言的編譯分為預(yù)處理、編譯、匯編、鏈接(test.c test.h => test.i => test.s => test.o => test)四個大的階段。c文件中的#include宏處理,會在預(yù)處理的階段將c中引用的h文件的內(nèi)容全部寫到c文件中,最后生成.i中間文件,這時h 文件中的內(nèi)容就相當(dāng)于被寫道c文件中。

        這也為代碼的復(fù)用提供了渠道,很多的c文件可以去引用同一個h文件,這樣這個h文件就會被放到多個c文件中被編譯多 次,這也是h文件中不能放定義只能放聲明的原因,放定義時被編譯多次,在程序鏈接的時候(系統(tǒng)中定義了多個int a;強(qiáng)符號定義)會出現(xiàn)錯誤, 聲明就不一樣,聲明表示對定義的擴(kuò)展,最終都會終結(jié)到一個定義上,所以不會出現(xiàn)link時重復(fù)定義的錯誤。

        編程中我們在h文件中肯定都用過一下的格式

        #ifndef  XXX_H #define  XXX_H  //…… #endif

        呵呵,那他到底有什么用呢,在h文件互相引用時,消除重復(fù)定義。當(dāng)然宏定義是在預(yù)處理階段發(fā)揮作用的,編譯方后的過程是沒有宏的影子的。

        A.h int a();    B.h #include "A.h"    C.h #include "A.h"    D.h #include "A.h" #include "B.h"

        上面的D.h文件中就會重復(fù)出現(xiàn)兩個int a();的聲明阿,這樣就有點(diǎn)重復(fù)了,這時條件編譯宏就派上了用場

        A.h #ifndef A_H #define A_H int a(); #endif

        這樣就不會重復(fù)定義了。

        推薦教程:《C#》

        贊(0)
        分享到: 更多 (0)
        網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號
        主站蜘蛛池模板: 久久亚洲精品视频| 欧美成人精品第一区二区三区 | 免费精品国产自产拍在线观看| 成人午夜精品视频在线观看| 亚洲精品蜜桃久久久久久| 久久久WWW免费人成精品| 国产精品99久久精品爆乳| 国产精品久久久久9999高清| 精品久久久久久国产潘金莲| 最新精品露脸国产在线 | 自拍偷在线精品自拍偷| 欧美精品人爱a欧美精品| 国产精品亚洲αv天堂无码| 2020最新久久久视精品爱| 久久精品国产亚洲麻豆| 国产精品欧美一区二区三区不卡 | 精品欧美| 国产午夜精品理论片| 国产精品久久久久久久午夜片| 午夜精品视频在线观看| 青青草国产精品久久| 日本精品中文字幕| 精品国产第1页| 久久免费精品一区二区| 欧洲精品视频在线观看| 国产成人毛片亚洲精品| 国产精品秘入口福利姬网站 | jizz国产精品| 国产成人精品综合在线观看| 国产福利电影一区二区三区,亚洲国模精品一区 | 久久久精品久久久久久| 欧美久久亚洲精品| 亚洲日韩国产精品乱| 无码人妻精品一区二区三区东京热| 四虎影视永久在线观看精品| 久久久久久久久无码精品亚洲日韩| 久久99精品久久久久婷婷| 国产福利精品一区二区| 久久er国产精品免费观看2| 99久久精品免费| 久久久久久极精品久久久 |