• 好运11选5官网

  • 好运11选5官网

  • 好运11选5官网

  • 好运11选5官网

好运11选5官网

作者︰whl  發布日期︰2020-02-23 16:18:00
  •   說到C++估計沒有人不知道的吧?這款編寫程序的編程語(yu)言(yan)的出現(xian)可以說為我(wo)們提供了很(hen)多的方便(bian),很(hen)多我(wo)們在使用的程序都是(shi)用它編寫出來(lai)的。下面小編就給大家詳細介紹(shao)一下關于C++語(yu)言(yan)里的文(wen)件以及源(yuan)文(wen)件的一些相關知識的介紹(shao),想要學(xue)習an)嗟吶笥you)不妨跟著小編一起繼續學(xue)習一番(fan)。

      C++中的頭文(wen)件和源(yuan)文(wen)件詳解

      一、C++編譯模(mo)式

      通(tong)常,在一個C++程序中,只包含(han)兩類(lei)文(wen)件——.cpp文(wen)件和.h文(wen)件。其中,.cpp文(wen)件被稱作C++源(yuan)文(wen)件,里面放的都是(shi)C++的源(yuan)代(dai)碼;而.h文(wen)件則(ze)被稱作C++頭文(wen)件,里面放的也是(shi)C++的源(yuan)代(dai)碼。

      C+ +語(yu)言(yan)支持(chi)“分別編譯”(separate compilation)。也就是(shi)說,一個程序所有的內容(rong),可以分成不同的部分分別放在不同的.cpp文(wen)件里。.cpp文(wen)件里的東(dong)西(xi)都是(shi)相對獨(du)立的mo) 詒譯(compile)時不需要與其他(ta)文(wen)件互通(tong),只需要在編譯成目(mu)標文(wen)件後再與其他(ta)的目(mu)標文(wen)件做一次鏈接(link)就行(xing)了。比如,在文(wen)件a.cpp中定(ding)義(yi) 了一個全局函數“void a() {}”,而在文(wen)件b.cpp中xing)枰 diao)用這個函數。即使這樣,文(wen)件a.cpp和文(wen)件b.cpp並不需要相互知道對方的存在,而是(shi)可以分別地對它們進行(xing)編譯, 編譯成目(mu)標文(wen)件之後再鏈接,整個程序就可以運行(xing)了。

      這是(shi)怎麼實現(xian)zhi)哪從寫程序的角qian)壤lai)講,很(hen)簡單。在文(wen)件b.cpp中,在調(diao)用 “void a()”函數之前,先(xian)聲(sheng)明一下這個函數“void a();”,就可以了。這是(shi)qie)蛭 嘁肫髟詒嘁.cpp的時候會生成一個符號表(symbol table),像(xiang)“void a()”這樣的mu)床壞蕉ding)義(yi)的符號,就會被存放在這個表中。再進行(xing)鏈接的時候,編譯器就會在別的目(mu)標文(wen)件中去尋找這個符號的定(ding)義(yi)。一旦找到了,程序也就可以 順利(li)地生成了。

      注意這里提到了兩個概念,一個是(shi)“定(ding)義(yi)”,一個是(shi)“聲(sheng)明”。簡單地說,“定(ding)義(yi)”就是(shi)把一個符號完完整整地描(miao)述(shu)出來(lai)︰它是(shi)變 量還(huai)是(shi)函數,返回(hui)什麼類(lei)型,需要什麼參wen)鵲取6ldquo;聲(sheng)明”則(ze)只是(shi)聲(sheng)明這個符號的存在,即告訴編譯器,這個符號是(shi)在其他(ta)文(wen)件中定(ding)義(yi)的mo) wo)這里先(xian)用著,你鏈接 的時候再到別的地方去找找看它到底是(shi)什麼吧。定(ding)義(yi)的時候要按C++語(yu)法完整地定(ding)義(yi)一個符號(變量或者函數),而聲(sheng)明的時候就只需要寫出這個符號的原型了。 需要注意的是(shi),一個符號,在整個程序中可以yuan)簧sheng)明多次,但卻(que)要且(qie)僅要被定(ding)義(yi)一次。試想,如果一個符號出現(xian)了兩種不同的定(ding)義(yi),編譯器該听誰的?

      這 種機制給C++程序員(yuan)們帶(dai)來(lai)了很(hen)多好處,同時也引出了一種編寫程序的方法。考慮qie)幌攏 綣幸桓齪hen)常用的函數“void f() {}”,在整個程序中的許多.cpp文(wen)件中都會被調(diao)用,那麼,我(wo)們就只需要在一個文(wen)件中定(ding)義(yi)這個函數,而在其他(ta)的文(wen)件中聲(sheng)明這個函數就可以了。一個函數還(huai) 好對付,聲(sheng)明起來(lai)也就一句話。但是(shi),如果函數多了,比如是(shi)qie)淮蠖訓氖xue)函數,有好幾百(bai)個,那怎麼辦(ban)?能(neng)保證每個程序員(yuan)都可以完完全全地把所有函數的形wen)蕉準確地記下來(lai)並寫出來(lai)嗎(ma)?

      二、什麼是(shi)頭文(wen)件

      很(hen)顯然,答案(an)是(shi)不可能(neng)。但是(shi)有一個很(hen)簡單地辦(ban)法,可以幫助(zhu)程序員(yuan)們省(sheng)去記住那麼多函數原型的麻(ma)煩︰我(wo)們可以把那幾百(bai)個函數的na)sheng)明語(yu)句全都先(xian)寫好,放在一個文(wen)件里,等到程序員(yuan)需要它們的時候,就把這些東(dong)西(xi)全部copy進他(ta)的源(yuan)代(dai)碼中。

      這 個方法固然可行(xing),但還(huai)是(shi)太麻(ma)煩,而且(qie)還(huai)顯得很(hen)笨(ben)拙(zhuo)。于是(shi),頭文(wen)件便(bian)可以發揮它的作用了。所謂的頭文(wen)件,其實它的內容(rong)跟.cpp文(wen)件中的內容(rong)是(shi)qie)謊模(mo) 際shi) C++的源(yuan)代(dai)碼。但頭文(wen)件不用被編譯。我(wo)們把所有的函數聲(sheng)明全部放進一個頭文(wen)件中,當某一個.cpp源(yuan)文(wen)件需要它們時,它們就可以通(tong)過一個宏命令 “#include”包含(han)進這個.cpp文(wen)件中,從而把它們的內容(rong)合並到.cpp文(wen)件中去。當.cpp文(wen)件被編譯時,這些被包含(han)進去的.h文(wen)件的作用便(bian)發 揮了。

      舉一個例子(zi)吧,假設所有的數學(xue)函數只有兩個︰f1和f2,那麼我(wo)們把它們的定(ding)義(yi)放在math.cpp里︰

    定(ding)義(yi)放在math.cpp

      並把“這些”函數的na)sheng)明放在一個頭文(wen)件math.h中︰

    頭文(wen)件math.h

      在另一個文(wen)件main.cpp中,我(wo)要調(diao)用這兩個函數,那麼就只需要把頭文(wen)件包含(han)進來(lai)︰

    頭文(wen)件包含(han)進來(lai)

      這 樣,便(bian)是(shi)qie)桓 暾某絛蛄恕P枰  獾氖shi),.h文(wen)件不用寫在編譯器的命令之後,但它必須要在編譯器找得到的地方(比如跟main.cpp在一個目(mu)錄下)。 main.cpp和math.cpp都可以分別通(tong)過編譯,生成main.o和math.o,然後再把這兩個目(mu)標文(wen)件進行(xing)鏈接,程序就可以運行(xing)了。

      三、#include

      #include 是(shi)qie)桓隼lai)自C語(yu)言(yan)的宏命令,它在編譯器進行(xing)編譯之前,即在預(yu)編譯的時候就會起作用。#include的作用是(shi)把它後面所寫的那個文(wen)件的內容(rong),完完整整地、 一字不改(gai)地包含(han)到當前的文(wen)件中來(lai)。值(zhi)得一提的是(shi),它本身是(shi)沒有其它任何作用與副功(gong)能(neng)的mo) 淖饔鎂褪shi)把每一個它出現(xian)zhi)牡胤劍 婊huan)成它後面所寫的那個文(wen)件的 內容(rong)。簡單的文(wen)本替換(huan),別無其他(ta)。因此,main.cpp文(wen)件中的第一句(#include "math.h"),在編譯之前就會被替換(huan)成math.h文(wen)件的內容(rong)。即在編譯過程將要開始的時候,main.cpp的內容(rong)已(yi)經發生了改(gai)變︰

    main.cpp的內容(rong)

      不多不少,剛剛好。同理可知,如果我(wo)們除了main.cpp以外,還(huai)有其他(ta)的很(hen)多.cpp文(wen)件也用到了f1和f2函數的話,那麼它們qie)餐tong)通(tong)只需要在使用這兩個函數前寫上一句#include "math.h"就行(xing)了。

      四、頭文(wen)件中應該寫什麼

      通(tong) 過上面的討(tao)論,我(wo)們可以了解到,頭文(wen)件的作用就是(shi)被其他(ta)的.cpp包含(han)進去的。它們本身並不參與編譯,但實際上,它們的內容(rong)卻(que)在多個.cpp文(wen)件中得到了 編譯。通(tong)過“定(ding)義(yi)只能(neng)有一次”的規則(ze),我(wo)們很(hen)容(rong)易可以得出,頭文(wen)件中應該只放變量和函數的na)sheng)明,而不能(neng)放它們的定(ding)義(yi)。因為一個頭文(wen)件的內容(rong)實際上xian)shi)會被引 入(ru)到多個不同的.cpp文(wen)件中的mo) ?qie)它們qian)薊岊槐嘁搿7派sheng)明當然沒事,如果放了定(ding)義(yi),那麼也就相當于在多個文(wen)件中出現(xian)了對于一個符號(變量或函數)的定(ding) 義(yi),縱然這些定(ding)義(yi)都是(shi)相同的mo)  雜詒嘁肫骼lai)說,這樣做不合法。

      所以,應該記住的一點就是(shi),.h頭文(wen)件中,只能(neng)存在變量或者函數的na)sheng)明, 而不要放定(ding)義(yi)。即,只能(neng)在頭文(wen)件中xing)蔥穩紓xtern int a;和void f();的句子(zi)。這些才是(shi)聲(sheng)明。如果寫上int a;或者void f() {}這樣的句子(zi),那麼一旦這個頭文(wen)件被兩個或兩個以上的.cpp文(wen)件包含(han)的話,編譯器會立馬報錯(cuo)。(關于extern,前面有討(tao)論過,這里不再討(tao)論定(ding)義(yi)跟 聲(sheng)明的區別了。)但是(shi),這個規則(ze)是(shi)有三個例外的。

      一,頭文(wen)件中可以寫const對象的定(ding)義(yi)。因為全局zhi)onst對象默 認xian)shi)沒有extern的na)sheng)明的mo) 運輝詰鼻拔wen)件中有xing)?0顏庋畝韻笮唇肺wen)件中,即使它被包含(han)到其他(ta)多個.cpp文(wen)件中,這個對象也都只在包含(han)它的 那個文(wen)件中有xing)? 雲淥ta)文(wen)件來(lai)說是(shi)不可見的mo) 員(yuan)bian)不huan)岬賈露嘀囟ding)義(yi)。同時,因為這些.cpp文(wen)件中的該對象都是(shi)從一個頭文(wen)件中包含(han)進去的mo) 庋簿捅V了這些.cpp文(wen)件中的這個const對象的值(zhi)是(shi)相同的mo) 晌揭瘓倭降謾M 恚tatic對象的定(ding)義(yi)也可以放進頭文(wen)件。

      二,頭文(wen)件中可 以寫內聯函數(inline)的定(ding)義(yi)。因為inline函數是(shi)需要編譯器在遇(yu)到它的地方根據(ju)它的定(ding)義(yi)把它內聯展(zhan)開的mo)  fei)是(shi)普通(tong)函數那樣可以先(xian)聲(sheng)明再鏈 接的(內聯函數不huan)崍唇,所以yuan)嘁肫 托枰 詒嘁朧笨(ben)吹僥諏  耐暾ding)義(yi)才行(xing)。如果內聯函數像(xiang)普通(tong)函數一樣只能(neng)定(ding)義(yi)一次的話,這事兒就難辦(ban)了。因為在 一個文(wen)件中還(huai)好,我(wo)可以把內聯函數的定(ding)義(yi)寫在最(zui)開始,這樣可以yuan)V?竺媸褂玫氖焙蚨伎梢約蕉ding)義(yi);但是(shi),如果我(wo)在其他(ta)的文(wen)件中還(huai)使用到了這個函數那怎麼辦(ban) 呢?這幾乎沒什麼太好的解決辦(ban)法,因此C++規定(ding),內聯函數可以在程序中定(ding)義(yi)多次,只要內聯函數在一個.cpp文(wen)件中只出現(xian)一次,並且(qie)在所有的.cpp文(wen) 件中,這個內聯函數的定(ding)義(yi)是(shi)qie)謊模(mo) 湍neng)通(tong)過編譯。那麼顯然,把內聯函數的定(ding)義(yi)放進一個頭文(wen)件中是(shi)非(fei)常明智的做法。

      三,頭文(wen)件中可以寫類(lei) (class)的定(ding)義(yi)。因為在程序中創建一個類(lei)的對象時,編譯器只有在這個類(lei)的定(ding)義(yi)完全可見的情況下,才能(neng)知道這個類(lei)的對象應該如何布局,所以,關于類(lei)的 定(ding)義(yi)的要求,跟內聯函數是(shi)基本一樣的。所以把類(lei)的定(ding)義(yi)放進頭文(wen)件,在使用到這個類(lei)的.cpp文(wen)件中去包含(han)這個頭文(wen)件,是(shi)qie)桓齪hen)好的做法。在這里,值(zhi)得一提 的是(shi),類(lei)的定(ding)義(yi)中包含(han)著數據(ju)成員(yuan)和函數成員(yuan)。數據(ju)成員(yuan)是(shi)qie) 鵲驕ju)體的對象被創建時才會被定(ding)義(yi)(分配空間),但函數成員(yuan)卻(que)是(shi)需要在一開始就被定(ding)義(yi)的mo) 庖簿是(shi)我(wo)們通(tong)常所說的類(lei)的實現(xian)。一般(ban),我(wo)們的做法是(shi),把類(lei)的定(ding)義(yi)放在頭文(wen)件中,而把函數成員(yuan)的實現(xian)代(dai)碼放在一個.cpp文(wen)件中。這是(shi)可以的mo) 彩shi)很(hen)好的辦(ban)法。 不huai) huai)有另一種辦(ban)法。那就是(shi)直接把函數成員(yuan)的實現(xian)代(dai)碼也寫進類(lei)定(ding)義(yi)里面。在C++的類(lei)中,如果函數成員(yuan)在類(lei)的定(ding)義(yi)體中被定(ding)義(yi),那麼編譯器會視這個函數為 內聯的。因此,把函數成員(yuan)的定(ding)義(yi)寫進類(lei)定(ding)義(yi)體,一起放進頭文(wen)件中,是(shi)合法的。注意一下,如果把函數成員(yuan)的定(ding)義(yi)寫在類(lei)定(ding)義(yi)的頭文(wen)件中,而沒有xing)唇lei)定(ding)義(yi)中, 這是(shi)不合法的mo) 蛭 飧齪 稍yuan)此時就不是(shi)內聯的了。一旦頭文(wen)件被兩個或兩個以上的.cpp文(wen)件包含(han),這個函數成員(yuan)就被重定(ding)義(yi)了。

      以上就是(shi)今(jin)天給大家分享的關于C++中的頭文(wen)件和源(yuan)文(wen)件的相關內容(rong)介紹(shao)了,相信看了上面這些內容(rong)大家對于C++又了解了更多吧?如果大家還(huai)想了解更多關于C++的內容(rong)歡迎查看本站其他(ta)發文(wen),小編這里就不一一給大家進行(xing)介紹(shao)了。

好运11选5官网

About IT165 -廣告服務 -隱(yin)私聲(sheng)明 -版(ban)權申明 -免責條(tiao)款 -網站地圖 -網友(you)投稿 -聯系方式
本站內容(rong)來(lai)自于互聯網,僅供用于網絡技術學(xue)習,學(xue)習中請遵循(xun)相關法律(lv)法規
好运11选5官网 | 下一页