目录
相关原理
Keil编译器规则
重点知识.c文件和.h文件的处理方式和用途
为什么在 example.c文件中需要这条指令#include "example.h"
没有包含会怎么样
配置前提
首先没有提示重复定义.c文件进行报错的前提是,Keil5中没有添加这源文件(ascii_font.c) 但是在Drivers工程目录下面,文件是存在的
这里或许会有小伙伴会好奇,为什么没有提示,下面这个提示,因为他善!!!
Freertos_01\Freertos_01.axf: Error: L6200E: Symbol ascii_font multiply defined (by driver_oled.o and ascii_font.o).Not enough information to list image symbols.
相关原理
开个玩笑,这里需要理解编译器#include 这条指令到底干了什么事情,当你在某个源文件中使用 #include "ascii_font.c"
时,编译器实际上是将 ascii_font.c
文件的内容直接嵌入到包含它的源文件中。就像是在这个源文件的相应位置插入了 ascii_font.c
文件的内容一样。此时,编译器视为单个源文件在进行处理。
视为单个源文件进行编译处理事带着引入的.c文件的,也就是说#include "ascii_font.c"
这条指令会让 ascii_font.c 被编译一次。
Keil编译器规则
在Keil5和大多数C/C++的编译环境中,源文件.c文件,都是通过项目配置来编译的,也就是Keil的工程目录结构中,添加.c文件才编译,不添加就不编译。
#include 引入编译一次,Keil5本身没有编译,所以就报不了,重复定义这个错误,是因为#include "ascii_font.c"
在整个工程中,只被用了一次,多次使用肯定报错。
重点知识.c文件和.h文件的处理方式和用途
.c文件的处理方式,.c文件是源码文件,通常包含了,函数的实现和全局变量的定义,在项目构建的过程中,编译器会将文件编译为目标文件(.o或者.obj)文件
编译器编译的过程,只会编译在C项目中添加的.c文件,这个时候才会编译,如果只在文件夹中添加,但是在编译器中的工程目录结构下,没有添加这个时候是不会编译的。
所以在添加驱动函数的时候,一定要添加.c文件.h文件添不添加无所谓,引用就行了。
.h头文件处理方式,这个文件通常用于声明函数,变量和宏定义,这个文件不会被编译器,编译而是通过 #include预处理指令,引入在.c文件中包含, 在.c文件中 #include "ascii_font.c" 编译器会将 ascii_font.c 的内容直接插入到,使用#include调用的文件中。
总结:#include 的作用就是在编译器在预处理阶段,将一个文件的内容,复制到,另一个文件中,这种方式允许在.c文件中重复使用相同的声明,而不会导致重复定义。
为什么在 example.c文件中需要这条指令#include "example.h"
为什么每次在写驱动文件的时候,在.c文件中必须引入头文件作用是什么。
当我们在.c文件中引入.h文件,这个时候编译器在编译.c文件的时候,会自动检查 driver_lcd.h driver_lcd.c 函数声明和函数定义的情况是否相同,就是会帮你检测有没有在.h文件中有没有声明错误。
这样可以保证函数的声明和定义是一样的,不一样会报错,就是这条语句的作用。如果不一致编译器会报错,提示你去修改这个声明或者实现。
没有包含会怎么样
如果你不在 example.c
中包含 example.h
,那么函数的实现仍然有效,但你失去了编译时自动同步声明和实现的检查。例如,如果你修改了头文件中的声明,而忘记修改实现,可能会导致其他引用这个函数的 .c
文件编译失败,或者在运行时出现未定义行为。
同时,#include .h文件,在其他.c文件中,是为了告诉编译器,这个函数声明的存在,但是这里只有声明没有实现部分,在连接阶段,编译器会结合两个.c文件的内容,这样有了声明也有了实现,就能正常调用函数。
欢迎指正,希望对你,有所帮助!!!