关于头文件

自定义头文件通常放在使用该头文件的源文件所在的目录中,并使用 #include "MyHead.h" 来包含。 
头文件是不编译的,因为C语言编译过程之前有个预编译过程。在这个过程中用头文件中的内容替换源文件中“#include”命令,所以在编译器看来,没有头文件,只有源文件。预编译过程还包括条件编译
 头文件为了防止被重复包含,通常的格式是: 
#ifndef _MYHEAD_H_ 
#define _MYHEAD_H_ 
(这里是头文件的内容) 
#endif  
 
预处理预编译处理是指在编译系统对文件进行编译---词法分析、语法分析、代码生成及优化之前,对一些特殊的编译语句先进行处理,然后将处理结果与源程序一起编译,生成目标文件。
条件编译条件编译指令将决定那些代码被编译,而哪些是不被编译的。可以根据表达式的值或者某个特定的宏是否被定义来确定编译条件。
#endif用于结束条件编译,编译时与前面最近的#if   #ifdef或#ifndef作为一对,经常一起使用,编译两者之间的部分程序段。
简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程1.预处理阶段

2.词法与语法分析阶段

3.编译阶段,首先编译成纯汇编语句,再将之汇编成跟CPU相关的二进制码,生成各个目标文件(.obj文件)

4.连接阶段,将各个目标文件中的各段代码进行绝对地址定位,生成跟特定平台相关的可执行文件,当然,最后还可以用objcopy生成纯二进制码,也就是去掉了文件格式信息。(生成.exe文件)

编译器在编译时是以C文件为单位进行的,也就是说如果你的项目中一个C文件都没有,那么你的项目将无法编译,连接器是以目标文件为单位,它将一个或多个目标文件进行函数与变量的重定位,生成最终的可执行文件,在PC上的程序开发,一般都有一个main函数,这是各个编译器的约定,当然,你如果自己写连接器脚本的话,可以不用main函数作为程序入口!!!!

(main .c文件 目标文件.O 可执行文件 )

有了这些基础知识,再言归正传,为了生成一个最终的可执行文件,就需要一些目标文件,也就是需要C文件,而这些C文件中又需要一个main函数作为可执行程序的入口,那么我们就从一个C文件入手,假定这个C文件内容如下:

#include <stdio.h>

#include "mytest.h"

int main(int argc,char **argv)

{

test = 25;

printf("test.................%d\n",test);

}

头文件内容如下:

int test;

现在以这个例子来讲解编译器的工作:

1.预处理阶段:编译器以C文件作为一个单元,首先读这个C文件,发现第一句与第二句是包含一个头文件,就会在所有搜索路径中寻找这两个文件,找到之后,就会将相应头文件中再去处理宏,变量,函数声明,嵌套的头文件包含等,检测依赖关系,进行宏替换,看是否有重复定义与声明的情况发生,最后将那些文件中所有的东东全部扫描进这个当前的C文件中,形成一个中间“C文件”

2.编译阶段,在上一步中相当于将那个头文件中的test变量扫描进了一个中间C文件,那么test变量就变成了这个文件中的一个全局变量,此时就将所有这个中间C文件的所有变量,函数分配空间,将各个函数编译成二进制码,按照特定目标文件格式生成目标文件,在这种格式的目标文件中进行各个全局变量,函数的符号描述,将这些二进制码按照一定的标准组织成一个目标文件

3.连接阶段,将上一步成生的各个目标文件,根据一些参数,连接生成最终的可执行文件,主要的工作就是重定位各个目标文件的函数,变量等,相当于将个目标文件中的二进制码按一定的规范合到一个文件中再回到C文件与头文件各写什么内容的话题上:理论上来说C文件与头文件里的内容,只要是C语言所支持的,无论写什么都可以的,比如你在头文件中写函数体,只要在任何一个C文件包含此头文件就可以将这个函数编译成目标文件的一部分(编译是以C文件为单位的,如果不在任何C文件中包含此头文件的话,这段代码就形同虚设),你可以在C文件中进行函数声明,变量声明,结构体声明,这也不成问题!!!
那为何一定要分成头文件与C文件呢?又为何一般都在头件中进行函数,变量声明,宏声明,结构体声明呢?(头文件不定义,不初始化)而在C文件中去进行变量定义,函数实现呢??原因如下:

1.如果在头文件中实现一个函数体,那么如果在多个C文件中引用它,而且又同时编译多个C文件,将其生成的目标文件连接成一个可执行文件,在每个引用此头文件的C文件所生成的目标文件中,都有一份这个函数的代码,如果这段函数又没有定义成局部函数,那么在连接时,就会发现多个相同的函数,就会报错

2.如果在头文件中定义全局变量,并且将此全局变量赋初值,那么在多个引用此头文件的C文件中同样存在相同变量名的拷贝,关键是此变量被赋了初值,所以编译器就会将此变量放入DATA段,最终在连接阶段,会在DATA段中存在多个相同的变量,它无法将这些变量统一成一个变量,也就是仅为此变量分配一个空间,而不是多份空间,假定这个变量在头文件没有赋初值,编译器就会将之放入BSS段,连接器会对BSS段的多个同名变量仅分配一个存储空间

3.如果在C文件中声明宏,结构体,函数等,那么我要在另一个C文件中引用相应的宏,结构体,就必须再做一次重复的工作,如果我改了一个C文件中的一个声明,那么又忘了改其它C文件中的声明,这不就出了大问题了,程序的逻辑就变成了你不可想象的了,如果把这些公共的东东放在一个头文件中,想用它的C文件就只需要引用一个就OK了!!!这样岂不方便,要改某个声明的时候,只需要动一下头文件就行了

4.在头文件中声明结构体,函数等,当你需要将你的代码封装成一个库,让别人来用你的代码,你又不想公布源码,那么人家如何利用你的库呢?也就是如何利用你的库中的各个函数呢??一种方法是公布源码,别人想怎么用就怎么用,另一种是提供头文件,别人从头文件中看你的函数原型,这样人家才知道如何调用你写的函数,就如同你调用printf函数一样,里面的参数是怎样的??你是怎么知道的??还不是看人家的头文件中的相关声明啊!!!当然这些东东都成了C标准,就算不看人家的头文件,你一样可以知道怎么使用

 

 
 

 

### 回答1: 如果您在编译STM32代码时遇到了头文件路径未添加的错误,可以按照以下步骤解决: 1. 确认您的头文件是否位于正确的路径下,例如在您的项目文件夹中的"inc"文件夹内。 2. 在您的工程设置中,确保您已经添加了正确的头文件路径。这通常可以在IDE的“工程设置”或“项目属性”菜单中找到。如果您使用的是CubeMX,则可以在“Project Manager”中找到“Code Generator”选项卡,然后在“Advanced Settings”中添加您的头文件路径。 3. 如果您已经添加了正确的路径,但仍然遇到了该错误,请确保您的头文件名称拼写正确,大小写也正确。 4. 最后,您可以尝试在代码中直接使用相对路径来包含头文件。例如,如果您的头文件在“inc”文件夹中,您可以使用“#include "../inc/header.h"”来包含它。 如果您的问题仍然无法解决,请参考您的IDE或编译器的文档,或向相关论坛或社区寻求帮助。 ### 回答2: 在使用STM32开发板进行编程时,经常会遇到头文件路径未添加的错误问题,导致编译无法找到相应的头文件。这种错误通常出现在使用了自定义的头文件时。 当我们在工程中包含其他文件或库时,需要在代码中添加相应的头文件路径,以便编译器能够正确地找到这些文件。 解决这个问题的方法有以下几种: 1. 修改头文件路径:在使用IDE开发环境时,可以通过打开项目属性或构建设置等设置界面,将头文件路径添加到项目的搜索路径中。这样,编译器就可以在这些路径中查找需要的头文件。 2. 使用相对路径:如果头文件与代码文件在同一目录下,可以使用相对路径来引用头文件。例如,如果需要引用一个名为"header.h"的头文件,可以在代码中使用"include "header.h""来包含该头文件。 3. 使用绝对路径:如果头文件不在当前工程所在目录下,可以使用绝对路径来引用头文件。在代码中使用完整路径名,例如"include "C:/path/to/header.h""。 4. 检查头文件是否存在:如果以上方法仍无法解决问题,需要检查头文件是否存在于指定的路径中。可能是由于文件名错误或路径错误导致编译器无法找到头文件。 在解决这类问题时,我们需要仔细查看错误信息,了解具体的错误原因。通常,编译器会指出缺少的头文件名称和具体路径。根据这些信息,可以逐步排查问题并采取相应的解决措施。 需要注意的是,正确引用头文件路径是编写良好代码的重要一环。正确添加头文件路径可以确保编译器能够正确找到所需的头文件,从而顺利完成编译和构建过程。 ### 回答3: 在STM32开发中,如果在编译时出现"cannot open source input file"的错误提示,通常是由于头文件路径没有添加正确导致的。 在编译C/C++程序时,编译器需要找到程序中所引用的头文件头文件路径告诉编译器在哪里找到这些头文件。 要解决这个问题,我们需要在编译器的设置中添加正确的头文件路径。 首先,打开项目的工程文件,找到编译器的设置选项。这些设置通常包含在一个makefile或者一个配置文件中。 接下来,找到编译器设置中的头文件搜索路径(Include Directories)选项。这个选项通常以"-I"开头,后面跟着头文件所在的路径。 确保这个路径是正确的,包含了所有需要的头文件路径。如果头文件位于项目文件夹内的子文件夹中,可以使用相对路径来指定。 另外,还可以使用绝对路径来指定头文件路径,这样可以确保编译器一定能够找到这些头文件。 完成以上设置后,重新编译项目,这个错误应该就会消失了。 总结而言,解决STM32关于头文件路径没有添加错误问题,需要在项目的编译器设置中添加正确的头文件搜索路径。确保路径正确、包含所有需要的头文件路径,重新编译即可解决问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值