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

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 您好,可能是因为您在Keil5使用了不正确的头文件路径或者头文件名称错误导致的。请检查您的头文件路径和名称是否正确,并确保头文件已经正确添加到Keil5项目。如果问题仍然存在,请提供更多详细信息,以便我们更好地帮助您解决问题。 ### 回答2: 在Keil5,常常会遇到在include头文件报错问题。下面我将从以下几个方面分析如何解决这个问题。 1. 检查头文件路径是否正确 在Keil5头文件路径与程序路径以及Keil的工作目录有关系。如果头文件是相对路径,记得在include语句正确书写路径。如果使用绝对路径,需要确保路径正确。 2. 检查头文件是否存在 如果头文件路径正确,但仍然报错,可以检查一下该头文件是否真的存在于路径。如果不存在,需要把头文件添加到工程。 3. 检查头文件是否被多次引用 有候,同一个头文件被多次引用,就会引起编译错误。这,可以使用#ifndef编译指令来避免重复引用。 4. 检查头文件是否有缺少依赖 如果头文件有缺少的依赖关系,也有可能引起编译错误,这可以在头文件加入必要的依赖关系。 5. 检查编译器设置 Keil5有两种编译器模式,分别对应于C51和ARM编译器。如果你使用的是ARM编译器,需要把文件扩展名改为.c文件。 总结来说,Keil5出现include头文件报错问题,需要认真检查头文件路径是否正确、头文件是否存在、是否被多次引用、是否有缺少依赖以及编译器设置等多个方面。只有找到问题原因并进行有效的修改,才能保证程序编译无误。 ### 回答3: 在使用Keil5进行编程,蒙上头的一个常见问题include头文件报错。这种错误信息通常会提示程序员找不到所需要的头文件。出现这种情况的原因可能有很多,以下是解决方法: 1. 检查搜索路径头文件搜索路径能否正确设置 在Keil5的options里,选"C/C++"选项卡,然后选择"Directories", 即可看到包含一些搜索路径。一些平台库的路径应该在次包括。检查搜索路径是否正确设置。 2. 检查头文件路径标识符是否正确 在Keil5,头文件只需用 <> 或 "" 包裹即可。我们通常应该使用""标记,<>标记是用于搜索非本地路径头文件,如平台库头文件。确保头文件路径标识符正确,否则会引发include头文件报错。 3. 检查头文件内容 头文件可能被复制到错误的位置。有候,头文件可能包含了不符合语法规则的语句。对于这些情况,建议检查你的头文件是否符合对应的语言规范。如果语法有误,即使文件名正确,编译器也是无法正常编译的。 4. 检查头文件名称 在Keil5,为了简化文件名的命名,允许一个头文件有不止一个名称。但是,最好是使用正确的名称。 5. 检查链结器脚本 检查程序的连接文件是否正确。例如,在ARM平台上,连接器脚本可能需要设置一些参数,如内存布局或芯片特定的参数等 。 总之,在使用Keil5进行编程include头文件报错可能会影响到您的程序的正确性,因此需要非常小心。建议花些间仔细检查这些问题,以确保头文件能够被正常连接到您的程序

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值