您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > C/C++/C#

C语言头文件路径剖析

时间:2020-07-29 11:09:37  来源:  作者:

在一个软件项目中,如果需要在一个文件中包含另一个头文件时,一般有两种包含方式:

​​​​​#include <stdio.h>#include “module.h”

如果你引用的头文件是标准库的头文件或官方路径下的头文件,一般使用尖括号 <> 包含;如果你使用的头文件是自定义的或项目中的头文件,一般使用双引号 "" 包含。头文件路径一般分为绝对路径和相对路径:绝对路径以根目录 / 或者windows下的每个盘符为路径起点;相对路径则是以程序文件当前的目录为起点。

#include ”/home/wit/code/xx.h” //linux下的绝对路径#include “F:/litao/code/xx.h" //Windows下的绝对路径#include ”../lcd/lcd.h” //相对路径,..表示当前目录的上一层目录#include ”./lcd.h” //相对路径,.表示当前目录#include ”lcd.h” //相对路径,当前文件所在的目录

编译器在编译过程中会按照这些路径信息到指定的位置去查找头文件,然后通过预处理器作展开处理。在查找头文件的过程中,编译器会按照默认的搜索顺序到不同的路径下面去搜索,以 #include <xx.h> 为例,当我们使用尖括号 <> 包含一个头文件时,头文件的搜索顺序为:

• 通过GCC参数 gcc-I 指定的目录(注:大写的 i)

• 通过环境变量 CINCLUDEPATH 指定的目录

• GCC 的内定目录

• 搜索规则:当不同目录下存在相同的头文件时,先搜到哪个使用哪个,搜索停止

当我们使用双引号 “” 来包含头文件路径时,编译器会首先到项目当前目录去搜索需要的头文件,在当前项目目录下面搜不到,再到其他指定的路径下面去搜索:

• 项目当前目录

• 通过 GCC 参数 gcc-I 指定的目录

• 通过环境变量 CINCLUDEPATH 指定的目录

• GCC 的内定目录

• 搜索规则:当不同目录下存在相同的头文件时,先搜到那个使用哪个

在编译程序时,如果我们的头文件没有放到官方路径下面,我们可以通过 gcc -I 来指定头文件路径,编译器在编译程序时,就会到用户指定的路径目录下面去搜索该头文件。如果你不想通过这种方式,也可以通过设置环境变量来添加头文件的搜索路径。在 Linux 环境下我们经常使用的环境变量有:

• PATH: 可执行程序的搜索路径

• C_INCLUDE_PATH: C语言头文件搜索路径

• CPLUS_INCLUDE_PATH: C++头文件搜索路径

• LIBRARY_PATH: 库搜索路径

我们可以在一个环境变量内设置多个头文件搜索路径,各个路径之间使用冒号:隔开。如果你想每次系统开机,这个环境变量设置的路径信息都生效,可以将下面的 export 命令添加到系统的启动脚本::~/.bashrc文件中。

export C_INCLUDE_PATH=$C_INCLUDE_PATH:/path1:/path2

除此之外,我们也可以将头文件添加到 GCC 内定的官方目录下面。编译器在上面指定的各种路径下面找不到对应的头文件时,最后会到 GCC 的内定目录下面去寻找。这些目录是 GCC 在安装时,通过 --prefex 参数指定安装路径是指定的,常见的内定目录有:

​​​​​​​
/usr/include/usr/local/include/usr/include/i386-linux-gnu/usr/lib/gcc/i686-linux-gnu/5/include/usr/lib/gcc/i686-linux-gnu/5/include-fixed/usr/lib/gcc-cross/arm-linux-gnueabi/5/include

接下来我们做一个实验,看看实际情况跟上面说得是否一致:我们创建多个头文件module.h,分别将其放置到不同的目录下,在main()函数中分别#include这个头文件,观察程序的运行结果。

​​​​​​​
# mkdir /home/test# cd test# touch main.c module.h

main.c源文件的代码如下:

​​​​​​
// main.c#include <stdio.h>#include "module.h"int main (void){    printf("NUM = %dm, NUM");    return 0;}//#module.h#define NUM 10

在module.h中分别定义一个宏:NUM,然后将这个头文件拷贝到不同的目录下:

  • 将NUM定义为10,拷贝到/home/test目录下
  • 将NUM定义为20,将module.h拷贝到/usr/include目录下
  • 将NUM定义为30,将module.h拷贝到//usr

实验过程:

  • 只保留/home/test/module.h头文件,main.c中使用#include <module.h>,观察程序的编译运行结果
  • 只保留/home/test/module.h头文件,main.c中使用#include "module.h",观察程序的编译运行结果
  • 将module.h拷贝到/home/test、/usr/include目录下,分别定义为10、20,观察程序的运行结果
  • 将module.h拷贝到/usr/include目录下,main.c中使用#include "module.h",观察程序的运行结果

这一轮实验做下来,相信大家已经对头文件的搜索路径、搜索顺序就有了一个清晰的认识了。本文摘自《嵌入式C语言自我修养》9.4.6节:

C语言头文件路径剖析

 

想学习编程的小伙伴们可以转发+关注+私信回复:“资料”就可以拿到一份我为大家准备的C++编程学习资料(C/C++高级开发/Linux 服务器架构/ 大型互联网应用/分布式/高并发/大数据等资料)



Tags:C语言   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
1.字符串数组+初始化char s1[]="array"; //字符数组char s2[6]="array"; //数组长度=字符串长度+1,因为字符串末尾会自动添&lsquo;\0&lsquo;printf("%s,%c\n",s1,s2[2]);...【详细内容】
2021-12-08  Tags: C语言  点击:(46)  评论:(0)  加入收藏
一、问题提出问题:把m个苹果放入n个盘子中,允许有的盘子为空,共有多少种方法?注:5,1,1和1 5 1属同一种方法m,n均小于10二、算法分析设f(m,n) 为m个苹果,n个盘子的放法数目,则先对...【详细内容】
2021-11-17  Tags: C语言  点击:(46)  评论:(0)  加入收藏
前言很多事不深入以为自己懂了,但真正用到项目上,才发现了问题。曾以为自己写C语言已经轻车熟路了,特别是对软件文件的工程管理上,因为心里对自己的代码编写风格还是有自信的。(...【详细内容】
2021-08-27  Tags: C语言  点击:(83)  评论:(0)  加入收藏
C语言作为高级语言,用其编写的程序指令机器并不能识别,因此需要有一个编译器将其转换为机器可识别的二进制指令。C语言已经出现50多年的时间,其相关的编译器种类众多,从最早先的...【详细内容】
2021-08-24  Tags: C语言  点击:(130)  评论:(0)  加入收藏
一 什么是ANSI控制码(ANSI escape sequences)维基百科给出的解释如下:ANSI escape sequences are a standard for in-band signaling to control cursor location, color, font...【详细内容】
2021-08-02  Tags: C语言  点击:(167)  评论:(0)  加入收藏
字符分类: 宽字符函数普通C函数描述 iswalnum() isalnum() 测试字符是否为数字或字母 iswalpha() isalpha() 测试字符是否是字母 iswcntrl() iscntrl() 测试字符是否是控制符...【详细内容】
2021-07-19  Tags: C语言  点击:(131)  评论:(0)  加入收藏
取消宏定义定义变量的时候,不能够重复定义同名变量;同理,定义宏的时候,不可以重复定义同名的宏。例如:#define MAX 1000#define MAX 50此时,重复定义MAX宏,是不合法的代码。但是,我...【详细内容】
2021-07-13  Tags: C语言  点击:(122)  评论:(0)  加入收藏
函数参数传递指针变量在函数的定义中,函数的参数可以是各种变量,就包括指针变量。首先,我们来看看一个函数的定义:void func(char* p);该函数的名称叫做func,参数定义为 char* p...【详细内容】
2021-07-09  Tags: C语言  点击:(135)  评论:(0)  加入收藏
8 函数嵌套调用我们学习了函数的定义和使用,那么,函数在被调用之前,必须先进行定义或者声明。如下是一个程序测试例子: 程序运行结果如下: 可以看到,在main函数中调用了func函数。...【详细内容】
2021-07-03  Tags: C语言  点击:(342)  评论:(0)  加入收藏
程序输入与输出当我们操作一个linux终端的时候,执行linux命令程序,可以看到命令的输出信息,或者要求输入数据。那么,这些操作就是linux命令程序与用户进行交互。程序与用户的交...【详细内容】
2021-06-23  Tags: C语言  点击:(163)  评论:(0)  加入收藏
▌简易百科推荐
一、简介很多时候我们都需要用到一些验证的方法,有时候需要用正则表达式校验数据时,往往需要到网上找很久,结果找到的还不是很符合自己想要的。所以我把自己整理的校验帮助类分...【详细内容】
2021-12-27  中年农码工    Tags:C#   点击:(1)  评论:(0)  加入收藏
引言在学习C语言或者其他编程语言的时候,我们编写的一个程序代码,基本都是在屏幕上打印出 hello world ,开始步入编程世(深)界(坑)的。C 语言版本的 hello world 代码:#include <std...【详细内容】
2021-12-21  一起学嵌入式    Tags:C 语言   点击:(10)  评论:(0)  加入收藏
读取SQLite数据库,就是读取一个路径\\192.168.100.**\position\db.sqlite下的文件<startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0"/...【详细内容】
2021-12-16  今朝我的奋斗    Tags:c#   点击:(21)  评论:(0)  加入收藏
什么是shellshell是c语言编写的程序,它在用户和操作系统之间架起了一座桥梁,用户可以通过这个桥梁访问操作系统内核服务。 它既是一种命令语言,同时也是一种程序设计语言,你可以...【详细内容】
2021-12-16  梦回故里归来    Tags:shell脚本   点击:(16)  评论:(0)  加入收藏
一、编程语言1.根据熟悉的语言,谈谈两种语言的区别?主要浅谈下C/C++和PHP语言的区别:1)PHP弱类型语言,一种脚本语言,对数据的类型不要求过多,较多的应用于Web应用开发,现在好多互...【详细内容】
2021-12-15  linux上的码农    Tags:c/c++   点击:(17)  评论:(0)  加入收藏
1.字符串数组+初始化char s1[]="array"; //字符数组char s2[6]="array"; //数组长度=字符串长度+1,因为字符串末尾会自动添&lsquo;\0&lsquo;printf("%s,%c\n",s1,s2[2]);...【详细内容】
2021-12-08  灯-灯灯    Tags:C语言   点击:(46)  评论:(0)  加入收藏
函数调用约定(Calling Convention),是一个重要的基础概念,用来规定调用者和被调用者是如何传递参数的,既调用者如何将参数按照什么样的规范传递给被调用者。在参数传递中,有两个很...【详细内容】
2021-11-30  小智雅汇    Tags:函数   点击:(19)  评论:(0)  加入收藏
一、问题提出问题:把m个苹果放入n个盘子中,允许有的盘子为空,共有多少种方法?注:5,1,1和1 5 1属同一种方法m,n均小于10二、算法分析设f(m,n) 为m个苹果,n个盘子的放法数目,则先对...【详细内容】
2021-11-17  C语言编程    Tags:C语言   点击:(46)  评论:(0)  加入收藏
一、为什么需要使用内存池在C/C++中我们通常使用malloc,free或new,delete来动态分配内存。一方面,因为这些函数涉及到了系统调用,所以频繁的调用必然会导致程序性能的损耗;另一...【详细内容】
2021-11-17  深度Linux    Tags:C++   点击:(37)  评论:(0)  加入收藏
OpenCV(Open Source Computer Vision Library)是一个(开源免费)发行的跨平台计算机视觉库,可以运行在Linux、Windows、Android、ios等操作系统上,它轻量级而且高效---由一系列...【详细内容】
2021-11-11  zls315    Tags:C#   点击:(50)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条