前言
头文件有两种包含方式,一种是使用尖括号<>,另外一种是通过双引号""包含,例如:
#include <iostream>
#include "add.h"
那么今天就专门来聊一聊这两种方式的区别。
1.头文件的含义不同
使用尖括号<>和双引号""包含的头问价的含义是不同的。使用尖括号<>包含的头文件是一般来说,是库文件对应的头文件,而使用双引号包含的则是我们自己的编写的头文件。
我觉得库文件相关的头文件大致可以分为三类:
第一类:C/C++标准库对应的一些一些头文件。
包含标准库、STL、算法等相关的一些头文件,这些一般是编译器自带的,minGw的mingw64\lib\gcc\x86_64-w64-mingw32\8.1.0\include\c++目录下面就会有一些我常用到的头文件:iostream、string、vector等头文件。包含方式如下:
#include <iostream>
#include <string>
#include <vector>
第二类:操作系统的系统头文件。
如果要需要用到一些操作系统相关的接口函数,那么就需要包含这些接口函数的所在的头文件。比如Linux系统的系统头文件位于目录/usr/include/sys中,包含time.h、epoll.h、sem.h等头文件。该目录下所有的系统头文件列举如下:
包含方式如下:
#include <sys/epoll.h>
#include <sys/sem.h>
第三类:根据需要安装的一些特定功能库对应的头文件
比如大名鼎鼎的boost库,该库是为C++标准库提供的扩展的一些C++程序库的总称。在比如,如果我们要使用mysql数据库,肯定会先本地安装mysql数据库,安装好之后,本地就会包含mysql相关库的头文件。以linux系统为例,如果安装了boost或这mysql,就会目录/usr/include/boost以及/usr/include/mysql,这两个目录下面分别存放着boost库和mysql接口库相关的头文件。包含方式如下:
#include <boost/lambda/lambda.hpp>
#include <boost/any.hpp>
#include <mysql/mysql.h>
总的来说,如果是尖括号<>包含的头文件,一般是库文件对应的头文件,这些头文件要么是编译器或者操作系统自带的,要么是我们下载后安装的,反正不需要我们自己去编写,直接使用就可以了。
如果是双引号""包含的头文件,是我们自己编写的。
2. 查找的顺序和路径不同
我们知道在编译过程中,进行预处理的时候,会替换include后面的文件,因此必须知道文件的位置。 那么编译器是怎么查找的呢? 尖括号和""两种包含方式查找顺序是不一样的。双引号形式会查找当前目录,尖括号形式则不会。以linux系统为例,具体查找顺序和路径如下:
当前目录(仅双引号形式)
编译时指定的头文件目录(由gcc -I参数指定)
系统环境变量 CPLUS_INCLUDE_PATH(c++头文件)或 C_INCLUDE_PATH(c头文件)指定的目录
gcc默认目录:/usr/include;/usr/local/include;/usr/lib/gcc/x86_64-linux-gnu/5/include等(注:最后一个路径是gcc程序的库文件地址,各个用户的系统上可能不一样)
如果各目录下存在相同的文件,则先找到哪个就使用哪个,这时顺序很重要。特别注意,尖括号形式不查找当前目录。
gcc的默认目录与安装gcc时指定的–prefix有关,该值可通过 gcc -v查看,具体的目录可通过 echo | g++ -v -x c++ -E - 查看,如下:
值得注意的是,因为查找的路径不同,在包含头文件的时候需要特别注意指定头文件的路径。比如include<mysql/mysql.h>,由于mysql.h的完整路径为/usr/include/mysql/mysql.h,而gcc默认目录有/usr/include,因此在包含的时候只需要指定路径mysql/mysql.h即可。
【参考文章】
1、https://blog.csdn.net/guotianqing/article/details/104224439