C++ #include " " 與 <>有什麼區別?

在一些C++程序中經常看到例如:#include"dog.h" 和#include&的兩種include形式,那麼" " 與 &<&>有什麼區別呢,他們分別引入了何種頭文件,&<&>除了引入標準庫,還能在其他情況下使用嗎?


安裝的代碼用&<&>,抄襲的代碼用""


注意其實#include後接&<&>或""包含的文件都是以實現定義(或者說implementation-defined)的方式去搜索的,以""形式包含的文件在無法以這個形式定義的方式搜索時轉為使用&<&>形式包含的方法去搜索,而絕大多數實現里&<&>表示搜索系統+附加包含路徑中的文件,""表示搜索當前源文件所處路徑下的文件,這意味著在這些實現下以""形式包含的文件當無法在當前源文件所處路徑下搜索到文件時會轉而去搜索系統+附加包含路徑,而和之前一個答案不一致的是以&<&>形式包含則不會這麼做。

結論:當你使用的實現比較主流的時候,要包含在和你的源文件相同路徑下的文件請使用""形式包含,而當包含stl或你所使用的第三方庫等的文件時請在配置了相關路徑後使用&<&>形式包含,這樣可以減少編譯時搜索文件的時間,也可能減少不必要的歧義(例如源文件的當前路徑下有和你要包含的庫的文件重名的文件時)。

===========分割線說下面的東西比較離題所以可以直接跳過了_(:з」∠)_==========

彩蛋:對於不同主流實現的配置附加包含路徑的方法,部分實現可能有多種配置方法,僅介紹答主使用較多的方法。

MSVC:

(當使用VS之時)

在解決方案資源管理器中選中你要修改附加包含路徑的工程,點擊屬性按鈕或者點擊右鍵選擇屬性。

之後依次展開配置屬性-C/C++-常規,點擊附加包含目錄進行設置即可。可以使用宏等表示某些特殊路徑,注意只會修改當前選中的配置和平台的選項,如果你有轉到其他配置和平台的打算,請和答主一樣選中所有配置/平台。

(當使用命令行之時)

使用msbuild時直接在&節中修改即可,使用;來分隔每個路徑。使用cl時使用/I(Include的開頭字母,不是小寫L也不是數字1,下同)開關指定附加包含目錄,每個附加包含目錄都要分開用/I指定。

GCC/Clang:

使用-I開關指定附加包含路徑即可,和cl相似,每個附加包含目錄都要分開用-I指定。也可以設置環境變數C_INCLUDE_PATH(編譯C時的默認包含路徑)、CPLUS_INCLUDE_PATH(編譯C++時的默認包含路徑)或者CPATH(同時對C/C++起作用)。


從標準來看……

n4659, 19.2 Source file inclusion, 2

A preprocessing directive of the form

# include &< h-char-sequence &> new-line

searches a sequence of implementation-defined places for a header identified uniquely by the specified sequence between the &< and &> delimiters, and causes the replacement of that directive by the entire contents of the header. How the places are specified or the header identified is implementation-defined.

擁有此形式的預處理指令

# include &< h-char-sequence &> new-line

於一序列實現定義位置,查找由 &< 與 &> 分隔符之間的序列所唯一標識的頭文件,並導致該指令為頭文件的整體內容所替換。位置如何指定,或頭文件如何標識,是實現定義的。

n4659, 19.2 Source file inclusion, 3

A preprocessing directive of the form

# include " q-char-sequence " new-line

causes the replacement of that directive by the entire contents of the source file identified by the specified sequence between the " delimiters. The named source file is searched for in an implementation-defined manner. If this search is not supported, or if the search fails, the directive is reprocessed as if it read

# include &< h-char-sequence &> new-line

with the identical contained sequence (including &> characters, if any) from the original directive.

擁有此形式的預處理指令

# include " q-char-sequence " new-line

導致該指令為 " 分隔符間的序列所標識的源文件的整體內容所替換。指名的源文件以實現定義行為查找。若不支持此查找,或若查找失敗,則此指令以如同它從原指令,以相同的所含序列讀取

# include &< h-char-sequence &> new-line

(包含 &> 字元,若它存在)。

(C11 標準里也有一模一樣的話)

簡言之 #include &<&> 和 #include "" 都會在實現定義的位置查找文件,並將其包含。

區別是若 #include "" 查找成功,則遮蔽 #include &<&> 所能找到的同名文件;否則再按照 #include &<&> 的方式查找文件。另外標準庫頭文件都放在 #include &<&> 所查找的位置。

一般來說 #include &<&> 的查找位置是標準庫頭文件所在目錄, #include "" 的查找位置是當前源文件所在目錄。不過這些都可由編譯器調用參數等配置更改。


摘錄自c/c++中#include &<&>與#include""區別

&<&>先去系統目錄中找頭文件,如果沒有在到當前目錄下找。所以像標準的頭文件 stdio.h、stdlib.h等用這個方法。

而""首先在當前目錄下尋找,如果找不到,再到系統目錄中尋找。 這個用於include自定義的頭文件,讓系統優先使用當前目錄中定義的。


這段時間剛好用cpp寫了一個嵌入式通信的庫,""是你放在你程序目錄下的文件,而&<&>一般在把頭文件和編譯的庫文件給分離後,然後在build的時候設置一個include的文件夾後來進行引用的


來源 《C語言程序設計(第四版)》 譚浩強


〈〉是項目中的鏈接文件

「」搜索範圍更大


搜索的範圍不一樣,<>只搜索編譯器自帶的函數庫,找不到直接報錯。「」先搜索自定義的文件,找不到再從自定義函數庫找,找不到報錯。


從我這種小白的角度來說大概就是&<&>里放的是系統自帶的,""可以是系統自帶的也可以是自己寫的。歡迎指正。


stdinc路徑的頭文件用&<&>編譯參數帶-I的路徑頭文件的用&<&>

其他的用「」


推薦閱讀:

C++ 函數返回局部變數的std::move()問題?
在開發大C++工程的時候如何判斷和避免循環include?
為什麼C++使用sizeof關鍵字的時候不需要include <cstddef>頭文件就可以使用?
如何在C++中拋出一個編譯錯誤?
C++的RAND函數生成的值為什麼存在嚴重的不隨機性?

TAG:編程語言 | 編程 | CC |