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.hfun2.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" 2

int 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外的地址内容不会改变,直接复制到父层。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值