• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Chip Studio

            常用鏈接

            統(tǒng)計(jì)

            最新評(píng)論

            關(guān)于C/C++語(yǔ)言中頭文件的使用的一些看法

            一、  只有一個(gè)文件的情況

            先來(lái)看一下比較簡(jiǎn)單的情形,也就是只有一個(gè)文件的時(shí)候,一個(gè)程序是什么樣子的。

            //main.c

            #include <stdio.h>

             

            int main(int argc, char** args)

            {

                printf("Hello\n") ;

                return 0 ;

            }

            這個(gè)時(shí)候程序一目了然,我們很容易就可以看出它說(shuō)了什么。

             

            二、  多個(gè)源代碼文件的情況

            但是,隨著我們要編寫(xiě)的程序的規(guī)模不斷擴(kuò)大,我們不得不把一個(gè)源代碼文件拆分開(kāi),把具有一定功能的某些方法放到其它單獨(dú)的源碼文件中。比如像下面這樣:

            //main.c

            #include <stdio.h>

             

            int main(int argc, char** args)

            {

                sayhello() ;

                return 0 ;

            }

             

            //sayhello.c

            #include <stdio.h>

            int sayhello()

            {

                printf("Hello\n") ;

            }

            把功能放在了sayhello.c文件中,而main.c只放主函數(shù)的代碼。這樣看起來(lái)更加的清晰明快。雖然形式上分成多個(gè)文件,但編譯器在編譯的時(shí)候會(huì)自動(dòng)把它們連在一起,也就是說(shuō)它們還是相當(dāng)于在一個(gè)大文件中寫(xiě)代碼。但是如果我們啟圖分別編譯這兩個(gè)文件,然后再鏈接成一個(gè)可執(zhí)行程序的時(shí)候,就會(huì)發(fā)生錯(cuò)誤。原因在于main.c中使用了一個(gè)函數(shù)sayhello,這時(shí)編譯器并不知道sayhello是什么,因?yàn)橄鄬?duì)于main.c來(lái)說(shuō),它并不存在sayhello的定義和實(shí)現(xiàn)。所以,我們必須要在main.c中加入sayhello的聲明(只要聲明就夠了,不必再實(shí)現(xiàn)一次)。方法是加一句int sayhello() ;但問(wèn)題是,當(dāng)我們的工程越來(lái)越大的時(shí)候,我們總不能引用一個(gè)函數(shù)就寫(xiě)一下它的都聲明吧?

            三、  引入頭文件

            這時(shí)最好的解決辦法就是引用頭文件。就是編寫(xiě)一個(gè)與sayhello.c同名的文件sayhello.h,用于定義常量、結(jié)構(gòu),聲明函數(shù)等。具體的做法如下:

            //main.c

            #include <stdio.h>

            #include "sayhello.h"

             

            int main(int argc, char** args)

            {

                sayhello() ;

                return 0 ;

            }

             

            //sayhello.c

            #include <stdio.h>

            #include "sayhello.h"

            int sayhello()

            {

                printf("Hello\n") ;

            }

             

            //sayhello.h

            int sayhello() ;

             

            四、  說(shuō)說(shuō)include

            對(duì)于頭文件,我們應(yīng)僅把它看作是一個(gè)文本文件,它跟程序的代碼文件(即擴(kuò)展名為.c的文件)并不一樣。編譯器在編譯的過(guò)程中,只會(huì)處理代碼文件,而不會(huì)去管其它的頭文件。只有當(dāng)我們?cè)陬^文件中使用#include的時(shí)候,相應(yīng)的頭文件才會(huì)被包含進(jìn)來(lái)。編譯器只是在編譯前把#include所在的位置換成了相應(yīng)頭文件中的內(nèi)容罷了。

            使用<>括起來(lái)的是系統(tǒng)的默認(rèn)庫(kù)文件,也就是說(shuō)不用咱們自己去找這個(gè)文件所在的位置,只寫(xiě)一個(gè)名字,編譯器就自動(dòng)找到庫(kù)目錄中的文件了。而””括起來(lái)的正好相反,大多是我們自己編的代碼或引用的非標(biāo)準(zhǔn)C的庫(kù)文件,它要求給出文件所在的絕對(duì)地址或相對(duì)地址。比如說(shuō),如果你的庫(kù)目錄設(shè)成/usr/share/include,那么下面的寫(xiě)法是等價(jià)的:

            #include <stdio.h> == #include “/usr/share/include/stdio.h”

             

            五、  談?wù)勵(lì)^文件具體的使用

            道理都懂了,那么自己寫(xiě)程序時(shí),我的頭文件到底應(yīng)該怎么寫(xiě)呢?其實(shí),頭文件的寫(xiě)法很隨意,很多人都有自己的使用習(xí)慣。但是我自己的看法是,盡量模仿標(biāo)準(zhǔn)C的庫(kù)。現(xiàn)在就來(lái)研究一下吧。

            比如我們平時(shí)使用printf時(shí),我們都要包括一個(gè)頭文件,即stdio.h。它的特點(diǎn)是我在哪個(gè)代碼文件用到了這個(gè)庫(kù)中的函數(shù),我就在哪個(gè)代碼文件中包括它的頭文件;包含它后,我的代碼中不應(yīng)該引入錯(cuò)誤,引用的庫(kù)函數(shù)不應(yīng)該因?yàn)榇a文件中多引用了或少引用了一些其它的頭文件而出錯(cuò)。

            為了達(dá)到這個(gè)目標(biāo),我的做法是:每寫(xiě)一個(gè)代碼文件,就寫(xiě)一個(gè)對(duì)應(yīng)的頭文件;把所有的聲明、定義、結(jié)構(gòu)體、常量、宏放在頭文件中,而代碼實(shí)現(xiàn)絕對(duì)不放在頭文件中;對(duì)頭文件的抱含也放到頭文件中,代碼文件中不含include宏。

            下面看一些反例:

            反例1:

            //types.h

            typedef int status ;

             

            //sayhello.h

            status sayhello() ;

             

            //sayhello.c

            #include <stdio.h>

            #include "types.h"

            #include "sayhello.h"

             

            status sayhello()

            {

                printf("Hello!\n") ;

                return 0 ;

            }

             

            //main.c

            #include "sayhello.h"

             

            int main(int argc, char** argv)

            {

                sayhello() ;

                return 0 ;

            }

            sayhello的定義中,出現(xiàn)了一個(gè)自定義類(lèi)型status,它的聲明包括在types.h文件中。放對(duì)它的引用放在了sayhello.c中,這樣單獨(dú)編譯sayhello.c沒(méi)有任何問(wèn)題。可是當(dāng)編譯到main.c的時(shí)候,就出現(xiàn)問(wèn)題了,編譯報(bào)錯(cuò):找不到status的聲明。這是因?yàn)樵?/span>main.c中只抱括了sayhello.h,而它的聲明又需要types.h。所以,它出現(xiàn)了由于少引用types.h而發(fā)生的錯(cuò)誤。所以,我強(qiáng)調(diào)把所有的include都放到頭文件中去。如果這樣寫(xiě)則不會(huì)出問(wèn)題。

            //sayhello.h

            #include <stdio.h>

            #include "types.h"

             

            status sayhello() ;

             

            //sayhello.c

            #include "sayhello.h"

             

            status sayhello()

            {

                printf("Hello!\n") ;

                return 0 ;

            }

            //main.c

            #include "sayhello.h"

             

            int main(int argc, char** argv)

            {

                sayhello() ;

                return 0 ;

            }

            這樣就符合了前面提到的原則。不過(guò),我還可以做如下的改動(dòng):

            //main.c

            #include "sayhello.h"

            #include "types.h"

             

            int main(int argc, char** argv)

            {

                status s = sayhello() ;

                return 0 ;

            }

            在主程序中聲明了status類(lèi)型的變量s。根據(jù)上面的原則,哪里引用了它,哪里就包括它的頭文件,所以我們包括了types.h頭文件。有人會(huì)說(shuō):“沒(méi)有types.h,也一樣不會(huì)出錯(cuò)啊,在sayhello.h中不是引用過(guò)types.h嗎?”這樣做真的是多此一舉嗎?當(dāng)然不是,我覺(jué)得它是相當(dāng)有意義的。第一,它維護(hù)了我們自己定下的原則。保持一個(gè)不變的代碼習(xí)慣是很有好處的。第二,由于我們保證了頭文件中不加入實(shí)現(xiàn)性質(zhì)的代碼,只寫(xiě)些聲明類(lèi)的代碼,它們?cè)诰幾g時(shí)只是起來(lái)語(yǔ)法制導(dǎo)的作用,并不會(huì)被成為目標(biāo)程序的一部分,所以這樣寫(xiě)并不會(huì)造成浪費(fèi)。這也是提倡頭文件中不要夾雜代碼的一個(gè)原因。

            如果真的不想把頭文件編譯多次的話,還有一個(gè)辦法,如下:

            #ifndef _HEADER_FILE_

            #define _HEADER_FILE_

            //聲明部分

            //...........

            #endif

            這樣寫(xiě)可以保證編譯器只編譯一次,其中的_HEADER_FILE_自己定義的頭文件的唯一標(biāo)識(shí),只要?jiǎng)e跟常量定義和別的頭文件沖突,您喜歡叫它什么就叫它什么吧。^^

             

            六、  總結(jié)

            最后總結(jié)一下吧。如果當(dāng)你在編寫(xiě)自己龐大的代碼文件群的時(shí)候,遇到了一些猶豫,就想想上面的原則和應(yīng)用。當(dāng)因?yàn)轭^文件編譯出錯(cuò)的時(shí)候,考慮一下是否自己有哪些動(dòng)作違反了上面的原則。只要經(jīng)常思考,每個(gè)人都會(huì)總結(jié)是適合自己的使用習(xí)慣,盡量減少在這些程序員看來(lái)無(wú)關(guān)緊要的事情上出錯(cuò)的機(jī)會(huì)。以上只是本人自己使用習(xí)慣的一次總結(jié),不代表任何規(guī)范和標(biāo)準(zhǔn),歡迎善意的批評(píng)指正.^_^

            posted on 2008-02-26 14:04 MyChip 閱讀(2953) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): C/C++/CLI

            欧美va久久久噜噜噜久久| 国产精品99久久99久久久| 久久精品成人欧美大片| 久久精品国产国产精品四凭| 久久精品国产亚洲5555| 亚洲AV日韩精品久久久久久久| 久久天堂电影网| 久久精品人人做人人爽电影| 中文字幕久久欲求不满| 久久婷婷成人综合色综合| 久久精品亚洲福利| 99热成人精品热久久669| 久久无码专区国产精品发布| 26uuu久久五月天| 99久久综合狠狠综合久久止| 精品久久久久久国产| 久久综合狠狠综合久久97色| 久久99国产精品久久久| 久久中文骚妇内射| 亚洲乱码中文字幕久久孕妇黑人| 色婷婷噜噜久久国产精品12p| 久久91精品国产91久久户| 午夜久久久久久禁播电影| 伊人色综合久久天天人手人婷| 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区 | 亚洲国产精品一区二区三区久久 | 亚洲精品高清一二区久久| 91久久精品91久久性色| 一本色道久久综合亚洲精品| 亚洲一区精品伊人久久伊人| 四虎国产精品成人免费久久| 久久99精品久久久久久齐齐 | 国产精品成人久久久久久久| 精品久久香蕉国产线看观看亚洲| 69久久精品无码一区二区| 中文字幕久久精品无码| 亚洲国产精品无码久久久秋霞2| 亚洲AV日韩AV天堂久久| 久久久久女人精品毛片| 2020久久精品国产免费| 久久成人精品视频|