【转载】#pragma once与#ifndef #define #endif的区别
生活随笔
收集整理的這篇文章主要介紹了
【转载】#pragma once与#ifndef #define #endif的区别
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
一、相同點?
? ? ? ?兩者的共同點都是為了避免同一個文件被 include 多次,但是 #ifndef #define #endif 不只有這個作用。?
在能夠支持這兩種方式的編譯器上,二者并沒有太大的區(qū)別,但是兩者仍然還是有一些細微的區(qū)別。?
??
二、收集理解?
1.#pragma once?
? ? ? ?這個是編譯器相關(guān),就是說在這個編譯系統(tǒng)上能用,在其他編譯系統(tǒng)不一定行,即移植性差。不過現(xiàn)在基本上已經(jīng)是每個編譯器都有這個定義了。?
? ? ? ?此方式由編譯器保證同一個文件不會被包含多次。注意:這里所說的“同一個文件”是指物理上的一個文件,而不是指內(nèi)容相同的兩個文件。于是不必再費勁想個宏名了,當然也就可以避免宏的名字沖突問題了。?
缺點:如果某個頭文件有多份拷貝,本方法不能保證他們不被重復包含。?
舉例:在一般的 MFC 程序中可以看到?
?
其中 _MSC_VER 分解如下:??
MS:Microsoft(微軟)的簡寫??
C:MSC 就是 Microsoft 出的 C 編譯器??
VER:Version(版本)的簡寫?
#if _MSC_VER > 1000 的意思就是如果編譯器版本高于 1000(VC++5.0)?
可以看到:在 _MSC_VER 小于 1000 時,它對 #pragma once 是不支持的。?
2.#ifndef #define #endif?
? ? ? ?該方法與 C++ 語言相關(guān),是 C++ 語言中的宏定義,通過宏定義避免文件多次編譯。所以在所有支持 C++ 語言的編譯器上都是有效的。如果寫的程序要跨平臺,最好使用這種方式。該方式由于是 C++ 語言本身支持,所以移植性好。它依賴于宏名字不能沖突,這不光可以保證同一個文件不會被包含多次,也能保證內(nèi)容完全相同的兩個文件不會被不小心同時包含。另外,為了保證不同頭文件中的宏名不沖突,故采取類似于_ABC_H_的取名方式。其中,abc.h為當前頭文件名。?
??
舉例:常常在一些頭中可以看到?
?
缺點:如果不同頭文件的宏名不小心“撞車”,可能就會導致頭文件明明存在,編譯器卻硬說找不到聲明的狀況。但這個缺點恰恰是我們可以利用的優(yōu)點,#ifndef 方式可以通過前面介紹的特殊的宏的取名方式來避免名稱沖突問題,于是其缺點也就不復存在了,進而 #ifndef 方式就更常用了。?
三、相比之下?
1.性能上的區(qū)別?
? ? ? ?使用 #ifndef 的話,編譯器每次看到 #include 這個文件都需要讀入文件,解析代碼; 而使用 #pragma once 編譯器根本不會重復打開文件, 大大提高了效率。?
2.編碼風格上的區(qū)別?
? ? ? ?使用 #pragma once 的代碼簡潔,顯然比 #ifndef 要簡短許多,重要的是它避免了頭文件標號(如 __myheader_h__ )的重定義或者 #endif 包含范圍錯誤的情況。?
3.語意上的區(qū)別?
#pragma once 是針對文件的,它告訴編譯器,本文件只編譯一次。?
#ifndef #define #endif 只是針對文件中的某一個標號而言的,它能用于防止三個指令間所包含內(nèi)容的重復性處理。就這一點而言,后者更靈活。?
4.可移植性方面?
#pragma once 是微軟的開發(fā)工具中所使用的,如 .net,vc6 等工具可以完好的支持;?
#ifndef #define #endif 是標準里面的一部分,所以對于任何完好支持 C/C++ 的編譯器都能使用。顯而易見,后者的可移植性更高。??
四、引用通告?
? ? ? ?兩者的共同點都是為了避免同一個文件被 include 多次,但是 #ifndef #define #endif 不只有這個作用。?
在能夠支持這兩種方式的編譯器上,二者并沒有太大的區(qū)別,但是兩者仍然還是有一些細微的區(qū)別。?
??
二、收集理解?
1.#pragma once?
? ? ? ?這個是編譯器相關(guān),就是說在這個編譯系統(tǒng)上能用,在其他編譯系統(tǒng)不一定行,即移植性差。不過現(xiàn)在基本上已經(jīng)是每個編譯器都有這個定義了。?
? ? ? ?此方式由編譯器保證同一個文件不會被包含多次。注意:這里所說的“同一個文件”是指物理上的一個文件,而不是指內(nèi)容相同的兩個文件。于是不必再費勁想個宏名了,當然也就可以避免宏的名字沖突問題了。?
缺點:如果某個頭文件有多份拷貝,本方法不能保證他們不被重復包含。?
舉例:在一般的 MFC 程序中可以看到?
?
| 1 2 3 4 5 6 7 8 9 10 11 | #if !defined(AFX_STDAFX_H__32722022_E372_4A5C_8EC5_BBB243CEDE1D__INCLUDED_) #define AFX_STDAFX_H__32722022_E372_4A5C_8EC5_BBB243CEDE1D__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // TODO: reference additional headers your program requires here //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_STDAFX_H__32722022_E372_4A5C_8EC5_BBB243CEDE1D__INCLUDED_) |
其中 _MSC_VER 分解如下:??
MS:Microsoft(微軟)的簡寫??
C:MSC 就是 Microsoft 出的 C 編譯器??
VER:Version(版本)的簡寫?
#if _MSC_VER > 1000 的意思就是如果編譯器版本高于 1000(VC++5.0)?
可以看到:在 _MSC_VER 小于 1000 時,它對 #pragma once 是不支持的。?
2.#ifndef #define #endif?
? ? ? ?該方法與 C++ 語言相關(guān),是 C++ 語言中的宏定義,通過宏定義避免文件多次編譯。所以在所有支持 C++ 語言的編譯器上都是有效的。如果寫的程序要跨平臺,最好使用這種方式。該方式由于是 C++ 語言本身支持,所以移植性好。它依賴于宏名字不能沖突,這不光可以保證同一個文件不會被包含多次,也能保證內(nèi)容完全相同的兩個文件不會被不小心同時包含。另外,為了保證不同頭文件中的宏名不沖突,故采取類似于_ABC_H_的取名方式。其中,abc.h為當前頭文件名。?
??
舉例:常常在一些頭中可以看到?
?
| 1 2 3 4 | #ifndef __SOMEFILE_H__ #define __SOMEFILE_H__? // 一些聲明語句 #endif |
缺點:如果不同頭文件的宏名不小心“撞車”,可能就會導致頭文件明明存在,編譯器卻硬說找不到聲明的狀況。但這個缺點恰恰是我們可以利用的優(yōu)點,#ifndef 方式可以通過前面介紹的特殊的宏的取名方式來避免名稱沖突問題,于是其缺點也就不復存在了,進而 #ifndef 方式就更常用了。?
三、相比之下?
1.性能上的區(qū)別?
? ? ? ?使用 #ifndef 的話,編譯器每次看到 #include 這個文件都需要讀入文件,解析代碼; 而使用 #pragma once 編譯器根本不會重復打開文件, 大大提高了效率。?
2.編碼風格上的區(qū)別?
? ? ? ?使用 #pragma once 的代碼簡潔,顯然比 #ifndef 要簡短許多,重要的是它避免了頭文件標號(如 __myheader_h__ )的重定義或者 #endif 包含范圍錯誤的情況。?
3.語意上的區(qū)別?
#pragma once 是針對文件的,它告訴編譯器,本文件只編譯一次。?
#ifndef #define #endif 只是針對文件中的某一個標號而言的,它能用于防止三個指令間所包含內(nèi)容的重復性處理。就這一點而言,后者更靈活。?
4.可移植性方面?
#pragma once 是微軟的開發(fā)工具中所使用的,如 .net,vc6 等工具可以完好的支持;?
#ifndef #define #endif 是標準里面的一部分,所以對于任何完好支持 C/C++ 的編譯器都能使用。顯而易見,后者的可移植性更高。??
四、引用通告?
在總結(jié)的過程中,看了一些網(wǎng)頁,也引用到其中的一些內(nèi)容,現(xiàn)給出鏈接,這里僅供本人學習,謝謝引用到的作者。?
總結(jié)
以上是生活随笔為你收集整理的【转载】#pragma once与#ifndef #define #endif的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。