特黄特色三级在线观看免费,看黄色片子免费,色综合久,欧美在线视频看看,高潮胡言乱语对白刺激国产,伊人网成人,中文字幕亚洲一碰就硬老熟妇

學(xué)習(xí)啦>知識(shí)大全>知識(shí)百科>百科知識(shí)>

.c .h 文件的區(qū)別

時(shí)間: 映芳735 分享

  C語(yǔ)言中有.c和.h文件這兩種文件格式代碼,那么它們之間有什么區(qū)別,下面小編講一講之間有什么區(qū)別。

  一、編譯器

  c文件與.h文件有什么不同之處,首先需要弄明白編譯器的工作過(guò)程,一般說(shuō)來(lái)編譯器會(huì)做以下幾個(gè)過(guò)程:

  1.預(yù)處理階段

  2.詞法與語(yǔ)法分析階段

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

  4.連接階段,將各個(gè)目標(biāo)文件中的各段代碼進(jìn)行絕對(duì)地址定位,生成跟特定平臺(tái)相關(guān)的可執(zhí)行文件,當(dāng)然,最后還可以用objcopy生成純二進(jìn)制碼,也就是去掉了文件格式信息。

  編譯器在編譯時(shí)是以c文件為單位進(jìn)行的,也就是說(shuō)如果你的項(xiàng)目中一個(gè)c文件都沒(méi)有,那么你的項(xiàng)目將無(wú)法編譯,連接器是以目標(biāo)文件為單位,它將一個(gè)或多個(gè)目標(biāo)文件進(jìn)行函數(shù)與變量的重定位,生成最終的可執(zhí)行文件,在PC上的程序開(kāi)發(fā),一般都有一個(gè)main函數(shù),這是各個(gè)編譯器的約定,當(dāng)然,你如果自己寫(xiě)連接器腳本的話(huà),可以不用main函數(shù)作為程序入口。

  二、c文件

  有了這些基礎(chǔ)知識(shí),為了生成一個(gè)最終的可執(zhí)行文件,就需要一些目標(biāo)文件,也就是需要C文件,而這些C文件中又需要一個(gè)main函數(shù)作為可執(zhí)行程序的入口,那么我們就從一個(gè)C文件入手,假定這個(gè)C文件內(nèi)容如下:

  #include

  #include "mytest.h"

  int main(int argc,char **argv)

  {

  test = 25;

  printf("test.................%d\n",test);

  }

  三、h文件

  1,當(dāng)一個(gè)函數(shù)要經(jīng)常使用(比如有十幾個(gè)C文件使用它)時(shí),一般我都放在H文件里,并在前面加上__inline.對(duì)于__inline函數(shù),很多C文件都可以INCLUDE這個(gè)H文件,但是它好象只能被一個(gè)H文件INCLUDE,如果有兩個(gè)H文件INCLUDE它,就會(huì)出現(xiàn)編譯錯(cuò)誤。

  2,有些數(shù)組變量,其大小可能達(dá)十幾K,而且要賦初值,這就不放在C文件里了,要不人都蒙了。

  3,

  #ifndef _feed_dog_h

  #define _feed_dog_h

  extern void feed_dog(void);

  #endif

  mohanwei兄,是不是這樣定議了,這個(gè)feed_dog.h就可以無(wú)數(shù)次的被INCLUDE了。

  四、編譯器的工作

  1.預(yù)處理階段:編譯器以C文件作為一個(gè)單元,首先讀這個(gè)C文件,發(fā)現(xiàn)第一句與第二句是包含.h文件,就會(huì)在所有搜索路徑中尋找這兩個(gè)文件,找到之后,就會(huì)將相應(yīng).h文件中再去處理宏,變量,函數(shù)聲明,嵌套的.h文件包含等,檢測(cè)依賴(lài)關(guān)系,進(jìn)行宏替換,看是否有重復(fù)定義與聲明的情況發(fā)生,最后將那些文件中所有的東東全部掃描進(jìn)這個(gè)當(dāng)前的C文件中,形成一個(gè)中間“C文件”

  2.編譯階段,在上一步中相當(dāng)于將那個(gè).h文件中的test變量掃描進(jìn)了一個(gè)中間C文件,那么test變量就變成了這個(gè)文件中的一個(gè)全局變量,此時(shí),就將所有這個(gè)中間C文件的所有變量,函數(shù)分配空間,將各個(gè)函數(shù)編譯成二進(jìn)制碼,按照特定目標(biāo)文件格式生成目標(biāo)文件,在這種格式的目標(biāo)文件中進(jìn)行各個(gè)全局變量,函數(shù)的符號(hào)描述,將這些二進(jìn)制碼按照一定的標(biāo)準(zhǔn)組織成一個(gè)目標(biāo)文件

  3.連接階段,將上一步成生的各個(gè)目標(biāo)文件,根據(jù)一些參數(shù),連接生成最終的可執(zhí)行文件,主要的工作就是重定位各個(gè)目標(biāo)文件的函數(shù),變量等,相當(dāng)于將個(gè)目標(biāo)文件中的二進(jìn)制碼按一定的規(guī)范合到一個(gè)文件中

  五、c文件與h文件區(qū)別

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

  1.如果在h文件中實(shí)現(xiàn)一個(gè)函數(shù)體,那么如果在多個(gè)C文件中引用它,而且又同時(shí)編譯多個(gè)C文件,將其生成的目標(biāo)文件連接成一個(gè)可執(zhí)行文件,在每個(gè)引用此h文件的C文件所生成的目標(biāo)文件中,都有一份這個(gè)函數(shù)的代碼,如果這段函數(shù)又沒(méi)有定義成局部函數(shù),那么在連接時(shí),就會(huì)發(fā)現(xiàn)多個(gè)相同的函數(shù),就會(huì)報(bào)錯(cuò)

  2.如果在h文件中定義全局變量,并且將此全局變量賦初值,那么在多個(gè)引用此h文件的C文件中同樣存在相同變量名的拷貝,關(guān)鍵是此變量被賦了初值,所以編譯器就會(huì)將此變量放入DATA段,最終在連接階段,會(huì)在DATA段中存在多個(gè)相同的變量,它無(wú)法將這些變量統(tǒng)一成一個(gè)變量,也就是僅為此變量分配一個(gè)空間,而不是多份空間,假定這個(gè)變量在h文件沒(méi)有賦初值,編譯器就會(huì)將之放入BSS段,連接器會(huì)對(duì)BSS段的多個(gè)同名變量?jī)H分配一個(gè)存儲(chǔ)空間

  3.如果在C文件中聲明宏,結(jié)構(gòu)體,函數(shù)等,那么我要在另一個(gè)C文件中引用相應(yīng)的宏,結(jié)構(gòu)體,就必須再做一次重復(fù)的工作,如果我改了一個(gè)C文件中的一個(gè)聲明,那么又忘了改其它C文件中的聲明,這不就出了大問(wèn)題了,程序的邏輯就變成了你不可想象的了,如果把這些公共的東東放在一個(gè)頭文件中,想用它的C文件就只需要引用一個(gè)就OK了!!!這樣豈不方便,要改某個(gè)聲明的時(shí)候,只需要?jiǎng)右幌耯文件就行了

  4.在h文件中聲明結(jié)構(gòu)體,函數(shù)等,當(dāng)你需要將你的代碼封裝成一個(gè)庫(kù),讓別人來(lái)用你的代碼,你又不想公布源碼,那么人家如何利用你的庫(kù)呢?也就是如何利用你的庫(kù)中的各個(gè)函數(shù)呢??一種方法是公布源碼,別人想怎么用就怎么用,另一種是提供頭文件,別人從頭文件中看你的函數(shù)原型,這樣人家才知道如何調(diào)用你寫(xiě)的函數(shù),就如同你調(diào)用printf函數(shù)一樣,里面的參數(shù)是怎樣的??你是怎么知道的??還不是看人家的頭文件中的相關(guān)聲明

538487