这两天被问到一个很有意思的问题:C头文件中尖括号与双引号有什么区别,以前只大约知道 <> 常用在系统库文件,"" 常用在自定义的借口文件中,那具体在gcc编译搜索过程中有啥区别,还得仔细查阅一番相关文档。

针对 <>  与 "" 的区别有如下解释:

摘抄自:https://gcc.gnu.org/onlinedocs/cpp/Include-Syntax.html#Include-Syntax

而在搜索时的区别,则做如下优先级排序:

摘抄自: https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html#Directory-Options

简单理解就是:

1. 尖括号告诉编译器去搜索标准系统目录,可使用 -I 选项添加其它搜索目录

2. 双引号告诉编译器先搜索以源文件路径为参考的目录,其次搜索引号目录,最后搜索标准系统目录, -iquote 选项可添加其它目录到引号目录列表中。

源文件路径为参考的目录

如何理解其含义呢,以实际情况为例,本地存在一个header/目录,其内部目录树结构如下所示:

图中的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" 。

C头文件中尖括号与双引号的区别及编译搜索顺序的更多相关文章

  1. C++包含头文件时尖括号和双引号区别

    原文链接:http://c.biancheng.net/cpp/biancheng/view/66.html 如果你还看一些别的C++教程,那么你可能很早就发现了,有些书上的#include命令写作# ...

  2. 转载 关于include尖括号和双引号的区别。

    对于使用尖括号( < >),预处理程序cpp在系统预设包含文件目录(如/usr/include)中搜寻相应的文件,而对于使用双引号(“ ”),cpp在当前目录中搜寻头文件,这个选项的作用是 ...

  3. C++中#include <xxx.h>和#include "xxx.h"的区别(尖括号和双引号的区别)

    第一种方式:采用< >方式,表示让编译器在编译器的预设标准路径下去搜索相应的头文件,如果找不到则报错. 例如:VS2015的安装目录\Microsoft Visual Studio 14. ...

  4. C++ #include—尖括号和双引号的区别

    如果你还看一些别的C++教程,那么你可能很早就发现了,有些书上的#include命令写作#include <文件名>,但有时候又会出现#include "文件名".你会 ...

  5. C语言中 单引号与双引号的区别

    在C语言中,字符用单引号,字符串用双引号.在c1='a';中,'a'是字符常量,必须用单引号."a"表示字符串,包含两个字符,一个是'a',一个是'\0'. 用数组来存储字符串. ...

  6. c语言头文件中定义全局变量的问题

    c语言头文件中定义全局变量的问题 (转http://www.cnblogs.com/Sorean/) 先说一下,全局变量只能定义在 函数里面,任意函数,其他函数在使用的时候用extern声明.千万不要 ...

  7. php 单双引号的区别

    在PHP中,字符串的定义可以使用英文单引号' ',也可以使用英文双引号" ". 但是必须使用同一种单或双引号来定义字符串,如:'Hello World"和"He ...

  8. PHP中单引号与双引号的区别

    在PHP中,字符串的定义可以使用英文单引号' ',也可以使用英文双引号" ". 一般情况下两者是通用的.但双引号内部变量会解析,单引号则不解析. PHP允许我们在双引号串中直接包含 ...

  9. 【转】perl中尖括号运算符(<>)使用说明

    perl中尖括号运算符的用途分享,这里简单介绍下,方便需要的朋友 perl中<>运算符可以有如下的用途: 1)如果尖括号中间是文件句柄,尖括号运算符允许你读取文件句柄,比如<STDI ...

随机推荐

  1. 全文搜索(A-2)-推荐算法

    一般来说推荐算法分为两类. 基于内容过滤的推荐: 基于协同过滤的推荐: 基于内容过滤的推荐,基于特征码描述项目. 协同过滤算法的设计基于一个假设,“和目标用户相似度高的用户,其感兴趣的物品目标用户也会 ...

  2. Elasticsearch的Java API做类似SQL的group by聚合。

    https://www.cnblogs.com/kangoroo/p/8033955.html

  3. UVALive7042(博弈论)

    题意: Bob和Alice在有向图内玩游戏,n个顶点,m条边. 每人一颗棋子,初始位置分别是x,y. Bob先手,轮流操作,每次只能走一条有向边. 结束条件: 1.不能操作的人输 2.两个棋子重合Bo ...

  4. Java高级教程:Java并发性和多线程

    Java并发性和多线程: (中文,属于人工翻译,高质量):http://ifeve.com/java-concurrency-thread-directory/ (英文):http://tutoria ...

  5. spring 数据源JNDI 基于tomcat mysql配置

    关键代码 <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean&q ...

  6. 得到java异常printStackTrace的详细信息

    平时写Java代码时,想看抛出的异常信息,来找出具体的异常点,我们常常会用Exception.toString ()或者 Exception.getMessage()来取得异常信息,再把它print到 ...

  7. maven bug之Maven:Non-resolvable parent POM: Failure to find错误

    使用Maven编译淘宝的TimeTunnel项目时遇到如下错误: [INFO] Scanning for projects...[ERROR] The build could not read 1 p ...

  8. SAS编程基础 - 逻辑库和数据集

    1. SAS逻辑库 1.1 创建SAS逻辑库: libname lb 'F:\Data_Model'; libname是关键字,lb是创建的逻辑库的名称,引号内的内容是目录路径,最后一个分号结束程序语 ...

  9. hibernate之多对一单向关联

    一个工作组(Group)里能够有多个用户(User),一个User仅仅属于一个Group,这是典型的多对一的关系. 在多对一的关系中正确的数据库设计是在多的这方(在这里是User这方)加一个Group ...

  10. MapReduce获取分片数目

    问题 MapReduce Application中mapper的数目和分片的数目是一样的,可是分片数目和什么有关呢? 默认情况下.分片和输入文件的分块数是相等的.也不全然相等,假设block size ...