C語言頭文件避免重復(fù)包含的方法技巧
C語言頭文件避免重復(fù)包含的方法技巧
假定有以下幾個(gè)頭文件及其包含關(guān)系為: File1.h,file2.h,file3.h,file4.h,file5.h,main.cpp 那么:file3.h包含file1.h,file2.h,file4.h包含file1.h,file2.h,file5.h包含file3.h,file4.h。如許就會(huì)導(dǎo)致在file5中對(duì)file1和file2的反復(fù)包含,編譯時(shí)就會(huì)報(bào)錯(cuò)。
關(guān)于頭文件重復(fù)包含問題
重復(fù)包含的影響:在預(yù)處理對(duì)時(shí)候,include相同的文件,預(yù)處理器會(huì)檢查XXX是否有定義再?zèng)Q定要不要**內(nèi)容,重復(fù)包含會(huì)是編譯器多檢查幾次而已。另外在使用增量編譯的時(shí)候,這個(gè)文件變化,所有include這個(gè)文件的文件都需要重新編譯,即使沒有去使用里面的任何內(nèi)容。
避免方法:1.把頭文件放在宏里:#ifndef標(biāo)志(這個(gè)標(biāo)志本來可以隨便自己定義,但是為了防止混亂百科,所以一般都會(huì)采用自己的文件名字:__WENJIAN_H__)#define標(biāo)志//文件內(nèi)容#endif在頭文件定義前面添加#pragmaonce(不太通用)就可以防止一個(gè)頭文件被多次包含,進(jìn)而防止重復(fù)定義的錯(cuò)誤。
在用VC6.0向?qū)傻念^文件中,經(jīng)??梢钥匆娙缦碌拇a段:#if!defined(AFX_RESIZABLELAYOUT_H__INCLUDED_)#defineAFX_RESIZABLELAYOUT_H__INCLUDED_#if_MSC_VER>1000#pragmaonce#endif//_MSC_VER>1000…#endif//!defined(AFX_RESIZABLELAYOUT_H__INCLUDED_)對(duì)于宏有基本了解的朋友應(yīng)該都知道,頭文件中如下的宏定義,是為了避免同樣的頭文件在同一個(gè).C文件或者.CPP文件多次包含。#if!defined(XXX)#defineXXX#endif這很好理解,但接下來的一段,尤其是#pragmaonce的意思,我就不是很清楚了。從MSDN得到pragmaonce的解釋是:\”Specifiesthatthefilewillbeincluded(opened)onlyoncebythecompilerwhencompilingasourcecodefile.\”英文注釋的大意也是說#pragmaonce是為了避免文件重復(fù)包含。疑惑就此產(chǎn)生了,既然宏\”#if!defined\”已經(jīng)有這個(gè)作用了,為何還要一個(gè)\”#pragmaonce\”呢?我接著在網(wǎng)上搜到了幾份答案,但大家的回答都很模糊,于是我想放棄,不再想這個(gè)問題,但還是不太甘心,就接著看了看別人的解釋。
突然間,好像靈犀一點(diǎn),開竅了。雖然\”#if!define\”和\”#pragmaonce\”都有避免重復(fù)包含的功能,但是在實(shí)現(xiàn)上還是有區(qū)別的。舉一例如下://Test1.h#if!define(__TESTONE_H_)#define__TESTONE_H_…#endif//Test2.h#pragmaonce…//Test.cpp#include\”Test1.h\”//line1#include\”Test1.h\”//line2#include\”Test2.h\”//line3#include\”Test2.h\”//line4…頭文件Test1.h中用宏來避免重復(fù),頭文件Test2.h中用#pragmaonce來避免重復(fù)。
編譯Test.cpp,將需要打開Test1.h兩次,**次發(fā)現(xiàn)宏__TESTONE_H_沒有定義,接著就處理宏定義;第二次打開Test1.h時(shí),發(fā)現(xiàn)宏__TESTONE_H_已經(jīng)定義過了,編譯器就會(huì)略過宏定義部分,知道處理完Test1.h末尾的#endif。而由于頭文件Test2.h使用#pragmaonce來避免重復(fù)定義的,在編譯Test.cpp的過程中,Test2.h只會(huì)被打開一次,也就是處理到第3行的時(shí)候。因?yàn)門est2.h用的是#pragmaonce,所以在處理完第3行后,編譯器已經(jīng)知道包含了一次Test2.h,在它(編譯器)處理第4行代碼時(shí),發(fā)現(xiàn)Test2.h已經(jīng)包含過了,忽略掉第4行代碼,也就不需要再次打開Test2.h進(jìn)行判斷了。
總結(jié)一下,除了#pragmaonce是微軟編譯器所特有的之外,用宏和#pragmaonce的辦法來避免重復(fù)包含頭文件,主要區(qū)別在于宏處理的方**多次打開同一頭文件,而#pragmaonce則不會(huì)重復(fù)打開,從而#pragmaonce能夠更快速。
頭文件被多次包含是什么意思?
頭文件被多次包含是:如有一個(gè)大型程序,為了提高可讀性,程序員是分多個(gè)文件編寫,不會(huì)寫在一個(gè)文件中的,這樣的話程序員把每個(gè)文件都包含到主程序所在的文件中,不能多次包含,否則會(huì)出現(xiàn)編譯出錯(cuò)!?。〉菐煳募脑捒梢远啻伟?,因?yàn)閹煳募蓄A(yù)編譯命令。預(yù)編譯命令是看條件編譯,如果條件成立編譯,否則不編譯,也就是你編譯一個(gè)文件時(shí)已經(jīng)編譯過這個(gè)頭文件,再編譯另一個(gè)文件時(shí)不會(huì)再編譯那條頭文件。
c語言如何避免重復(fù)包含頭文件?
#include 通常不會(huì)包含 .cpp 文件,如果包含的話,一般僅會(huì)包含如 static 的函數(shù)這樣不會(huì)因?yàn)槎啻伟鴮?dǎo)致鏈接問題的。為了防止重復(fù)包含,頭文件中都會(huì)有相應(yīng)的處理,比如加上#ifndef _STDIO_H_#define _STDIO_H_// 真正的頭文件內(nèi)容#endif這樣在多次包含的時(shí)候,因?yàn)橐呀?jīng)定義了 _STDIO_H_,所以第二次包含的內(nèi)容會(huì)被忽略。
比較新的 C++ 編譯器也支持 #pragma once,這樣只要在頭文件開頭寫上這一句,編譯器就會(huì)在處理頭文件的時(shí)候不包含多次了。
C語言 頭文件重復(fù)包含問題 inndef 怎么用?
#ifndef BASE_H//如果沒有定義過 BASE_H ,就編譯下面的代碼#define BASE_H//定義這個(gè)宏#endif 在每一個(gè).h文件,都使用這個(gè)編譯指令。即使多次 #include,也不會(huì)重復(fù)包含。
有關(guān)C++頭文件重復(fù)的問題
誰說重復(fù)包含就報(bào)錯(cuò)。
重復(fù)包含幾百次也不是什么錯(cuò), 如果有錯(cuò),錯(cuò)在里面的東西不可以重復(fù)出現(xiàn)多次, 而這里里面的東西重復(fù)出現(xiàn)是語法允許的, 所以當(dāng)然不會(huì)有什么錯(cuò)include**意義就是吧那個(gè)文件的內(nèi)容替換到這個(gè)位置來,沒別的講究 顯然我說的“東西”不是頭文件, 而是C語言的語法結(jié)構(gòu)。
首先你要搞清一個(gè)概念, #include是編譯預(yù)處理的語法結(jié)構(gòu), 而不是C語言的。 C語法本身并不知道#include的存在,所以它也不會(huì)在意你include多少次。 他在意的是, 比如如果你頭文件里有一個(gè)變量定義: int a =10; 那么當(dāng)你include這個(gè)頭文件多次展開后就定義了這個(gè)變量多次, 這當(dāng)然就違反C的語法規(guī)則。 所以是否可以include多次這個(gè)問題不在于include本身而在于展開后的結(jié)果是不是能接受。
現(xiàn)在所有標(biāo)準(zhǔn)頭文件都可以重復(fù)include而不會(huì)產(chǎn)生不良影響。 自己寫的頭文件在vc下可以**句加上#pragma once也就可以重復(fù)include。 別的頭文件只能說看情況。