include的头文件中include其他头文件时的路径问题
问题
由于之前项目做得很少,一直没有注意到这个问题,include一直认为就是直接把include的文件复制过来,并没有去深究里面的原理。但今天做项目时发现如果是直接复制过来,那include的文件里include的其他文件的地址岂不是就要填之前的源代码文件的相对地址了吗?(a引入b,b又要引入c)但这当然不符合常人的思想,毕竟这样工作的话如果另外一个文件也要用到这个头文件地址就乱了。
测试环境
- Windows 10
- Code::Blocks(编译器:MinGW-W64)
测试开始
首先建好一个main.c
的文件
#include <stdio.h>int main()
{return 0;
}
在main.c
文件目录下建一个include
文件夹,在include
文件夹中再建两个头文件fun1.h
和fun2.h
我们先试试如果是直接复制粘贴include的内容的情况,即include相对于源代码的地址
fun1.h
#include "include/fun2.h"
void fun1()
{}
fun2.h
void fun2()
{}
我们修改main.c
文件,引入fun1.h
#include "fun1.h"int main()
{return 0;
}
这样如果符合直接复制的这个猜想,得到的应该是这样的,似乎并没有什么问题。
#include "include/fun2.h"
void fun1()
{}int main()
{return 0;
}
编译结果:没有找到include/fun2.h
fatal error: include/fun2.h: No such file or directory|
我们再修改一下fun1.h
,将fun2.h
的地址改为相当于fun1.h
的地址
#include "fun2.h"
void fun1()
{}
编译运行 没有问题。
Process returned 0 (0x0) execution time : 0.016 s
Press any key to continue.
至此,我们已经可以确定,这种情况下我们include
的地址是要填写使用相对于include
的此文件的地址(即a引用b,b引用c时写c的地址要写相对于b而言的地址),这也是我们认知所更能接受的。我们去验证一下这个猜想是否正确。
验证
一个源文件在编译前还有一段预编译(预处理)阶段,这个阶段会把我们的include
全部去掉,变成include
的文件中的内容并全部内容整合到一个文件,我们找到我们的main.h
预编译后的文件,看看它到底是什么样的。
打开cmd命令行,调整到我们main.c
的目录,输入gcc -E main.c
(含义:预处理main.c
)我们得到的是
# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "main.c"
# 1 "include/fun1.h" 1
# 1 "include/fun2.h" 1
void fun2()
{}
# 2 "include/fun1.h" 2
void fun1()
{}
# 2 "main.c" 2int main()
{return 0;
}
我们可以发现,此时已经把#include "fun2.h"
替换为了"include/fun2.h"
,看来预处理是会把include
的地址处理成一个正确的地址的。
扩展
那include
的文件到底是只会把此文件include
其他文件的地址修改还是会把包括代码中的其他部分的地址全部修改呢
我们把fun1.h
添加点东西,现在fun1
的功能是创建一个名为kadia.txt
的文件
#include <stdlib.h>
#include "fun2.h"
void fun1()
{system("type nul>kadia.txt");
}
在main.c
中调用fun1
#include "include/fun1.h"int main()
{fun1();return 0;
}
编译运行后我们发现,在main.c
的目录下创建了一个kadia.txt
,而在include
目录中并没有,看来代码中的include外的地址并没有改变,而是直接复制了过来,这一点也在预编译的文件中得到了验证
# 1 "include/fun2.h"
void fun2()
{}
# 3 "include/fun1.h" 2
void fun1()
{system("type nul>kadia.txt");
}
总结
在多层的include
中,父层引入子层的include
文件时会在地址前加上子层的地址,即(a引入c时会在c的地址前加上b的地址),include
外的地址内容不会改变,直接复制到父层。
include的头文件中include其他头文件时的路径问题相关推荐
- 如何在另一个JavaScript文件中包含一个JavaScript文件?
JavaScript中是否有类似于CSS中@import的内容,可让您在另一个JavaScript文件中包含一个JavaScript文件? #1楼 而不是在运行时添加,而是使用脚本在上传之前进行串联. ...
- 批量提取出apk文件中的classes.dex文件
应用场景 如果需要批量分析apk以及每个apk文件中的classes.dex 文件.怎么提取出它们?将apk改后缀名变为.zip文件,之后在解压,提取出每个apk文件中的classes.dex文件,这 ...
- 在SCSS文件中导入常规CSS文件?
本文翻译自:Import regular CSS file in SCSS file? Is there anyway to import a regular CSS file with Sass's ...
- java jar metainf_java – 从生成的jar文件中排除META-INF / maven文件夹
我正在尝试创建一个jar文件,其中包含jar中提取的所有必需类.但对于像 log4j这样的少量依赖jar,它会在META-INF / maven / *中创建一些文件夹.我有一个限制,我将放置生成的j ...
- SQL导入文本错误:大容量插入: 在数据文件中遇到意外的文件结尾 (EOF)。
服务器: 消息 4832,级别 16,状态 1,行 1 大容量插入: 在数据文件中遇到意外的文件结尾 (EOF). 服务器: 消息 7399,级别 16,状态 1,行 1 OLE DB 提供程序 'S ...
- php获取curl头_php中CURL请求头和响应头获取方法
本文主要和大家分享php中CURL请求头和响应头获取方法,希望能帮助到大家. 1.从CURL中获取响应头$oCurl = curl_init(); // 设置请求头, 有时候需要,有时候不用,看请求网 ...
- C++:从json文件中读取参数/创建文件夹/位拼接
目录 1.从json文件中读取参数 2.创建文件夹 3.位运算拼接 1.从json文件中读取参数 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,和xml ...
- 批量从apk文件中提取出so文件
应用场景 在不解压apk文件夹的情况下批量的从apk文件中提取出所有的so文件.这样你即不用使用apktool 这些工具令产生大量的中间文件,或者将apk的后缀变为.zip,然后在解压,节省了磁盘空间 ...
- linux 查看文件中数据类型,Linux下使用file命令确定文件中数据的类型-文件类型...
青年是学习智慧的时期,中年是付诸实践的时期.--卢梭 在Linux系统中查看一个文件之前,要先确定该文件中数据的类型,之后再使用适当的命令或方法打开该文件. 与windows系统不同,在Linux系统 ...
最新文章
- javaweb中为mysql的curd多个值的语句
- ZLComboBox自定义控件开发详解
- 洛谷1020导弹拦截
- 鸿蒙开发-基础组件介绍及chart组件使用
- apk改之理_一份礼物.apk-O泡果奶的逆向分析
- leetcode 376. 摆动序列 思考分析
- golang中文文档_【译】Go 语言源码贡献官方指导文档
- django-普通的cookie操作
- MySQL中的DATE_SUB()函数和DATE_ADD()函数
- VINS-Mono代码分析与总结(完整版)
- VC++ Tab Control控件的使用
- 数据分析告诉你,历年的诺贝尔奖都被哪些人拿走了?
- [深度学习] ImageAI库使用笔记
- Bridge 双维度扩展
- 董卫凤:不服输的华丽转身(三)
- java 余弦定理_文本相似度计算之余弦定理
- oracle数据库修改pga,18.1.2 修改PGA
- 关于在Linux下无法查看caj文档的解决方案
- 转换器(Converter)Struts 2.0中的魔术师
- c语言 查看磁盘信息,获取磁盘列表以及磁盘信息的一些WIN32 API