這兩天被問到一個頗有意思的問題:C頭文件中尖括號與雙引號有什麼區別,之前只大約知道 <> 經常使用在系統庫文件,"" 經常使用在自定義的藉口文件中,那具體在gcc編譯搜索過程當中有啥區別,還得仔細查閱一番相關文檔。html
針對 <> 與 "" 的區別有以下解釋:shell
摘抄自:https://gcc.gnu.org/onlinedocs/cpp/Include-Syntax.html#Include-Syntax測試
而在搜索時的區別,則作以下優先級排序:spa
摘抄自: https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html#Directory-Options3d
簡單理解就是:htm
1. 尖括號告訴編譯器去搜索標準系統目錄,可以使用 -I 選項添加其它搜索目錄blog
2. 雙引號告訴編譯器先搜索以源文件路徑爲參考的目錄,其次搜索引號目錄,最後搜索標準系統目錄, -iquote 選項可添加其它目錄到引號目錄列表中。排序
源文件路徑爲參考的目錄文檔
如何理解其含義呢,以實際狀況爲例,本地存在一個header/目錄,其內部目錄樹結構以下所示:get
圖中的hello.c文件,是這樣包含頭文件的:#include "..inc/hello.h"
測試1. shell 處在 ~/header/src/ 目錄,跟蹤gcc 的編譯搜索過程: strace -f -o log gcc say_hello.c ,查看log輸出:
從圖中的搜索路徑可知:因源文件恰好處在gcc執行目錄下,所以在編譯時,源文件的相對執行目錄爲 . , dot默承認省略,再拼接上#include "../inc/hello.h" 引號內的路徑,那麼gcc會定位到 "../inc/say_hello.h" 去搜索hello.h文件
測試2. shell處在 ~/header/ 目錄,跟蹤gcc的編譯搜索過程:strace -f -o log gcc ../src/say_hello.c,查看log輸出:
從圖中搜索路徑可知:因源文件在gcc目錄的下一級目錄,所以在編譯時,源文件的相對執行目錄爲 src/ , 再拼接上 #include "../inc/hello.h" 引號內的路徑,那麼gcc會定位到 "src/../inc/say_hello.h" 去搜索hello.h文件.
因此從測試結果來看,gcc編譯時,以執行目錄爲參考點來定位源文件的路徑,再以源文件爲參考點來定位頭文件路徑。在上述測試中,~/header/src/say_hello.h 文件始終是被忽略的,除非代碼中寫成 #include "say_hello.h" 。