【头文件】对.h文件的理解

简介: 【头文件】对.h文件的理解

🌞1. 头文件的概念

🌊1.1 头文件的由来

在编译器只认识.c(.cpp)文件的年代,人们发现很多.c(.cpp)文件中的声明语句是相同的,但需要重复地敲入每个文件中,导致维护困难。为了解决这个问题,人们将重复的部分提取出来放在一个新文件中,即“头文件”,通常使用.h扩展名。这些头文件包含了变量和函数的全局性声明,被其他.c文件共享,方便修改和维护大型代码。因此,头文件中通常只包含声明而很少包含具体实现的代码。


🌊1.2 头文件的作用

头文件(通常以.h为扩展名)是用来声明变量、函数、宏等的文件,它通常包含在源代码文件中,用于向编译器提供关于程序中各种元素的信息。下面是关于头文件的一些常见理解:

  1. 声明和定义的分离:头文件包含了各种声明,如函数原型、变量声明、宏定义等,而对应的定义通常在其他的源代码文件中。这样做的好处是可以在程序中分离接口和实现,使得代码更具有模块化和可维护性。
  2. 共享代码:头文件可以被多个源代码文件引用,这样就可以在多个文件之间共享函数、变量等信息,避免了重复编写相同的代码,提高了代码的重用性。
  3. 编译优化:使用头文件可以让编译器在编译时对代码进行更好的优化,因为编译器可以在编译单个源文件时了解到所有需要的函数原型和变量声明,从而做出更好的优化决策。
  4. 可读性和维护性:头文件可以作为接口文档,向其他开发者传达关于函数、变量等的信息,提高了代码的可读性和可维护性。通过查看头文件,开发者可以快速了解程序的接口和结构。
  5. 预处理指令:头文件中通常包含预处理指令,如条件编译、宏定义等,用于控制代码的编译行为,实现跨平台兼容性、调试信息开关等功能。

总的来说,头文件在C/C++编程中扮演着非常重要的角色,它们不仅定义了程序的接口,还能提高代码的重用性、可读性和可维护性,是模块化编程的重要组成部分。


🌊1.3 在.h文件中实现函数也不会出错的原因

要解决上述问题,首先必须弄清编译器的工作原理。编译器的最终目的是将程序员编写的源代码转换成机器能够识别运行的二进制机器码

大体可分成 4 个步骤:

  1. 头文件的预编译,预处理
    编译器在编译源代码时,会先编译头文件,保证每个头文件只被编译一次。
    在预处理阶段,编译器将c文件中引用的头文件中的内容全部写到c文件中。
  2. 词法和语法分析(查错)
  3. 编译(汇编代码)
    转化为汇编码,这种文件称为目标文件。后缀为.obj。
  4. 链接(二进制机器码)
    将汇编代码转换为机器码,生成可执行文件。后缀为.exe。

在.h文件中实现函数不会出错的原因是因为.h文件的内容在预处理阶段被直接包含到调用它的源文件中,而在编译阶段,编译器只关注源文件的内容,而不关心它是如何被包含的。因此,将函数的实现放在.h文件中并不会导致编译错误。

然而,这种做法并不是推荐的编程习惯。通常,头文件应该只包含函数的声明和数据结构的定义,而不应该包含函数的实现。


🌞2. 简单示例

🌊2.1 头文件addition.h

addition.h内容如下:

#ifndef ADDITION_H
#define ADDITION_H
 
// 函数声明
int add(int a, int b);
 
#endif /* ADDITION_H */

补充:

头文件为什么喜欢写类似下面的内容:

#ifndef ADDITION_H 
#define ADDITION_H 
 
//内容。。。
 
#endif

这是头文件中常见的一种写法,被称为"头文件保护(Header Guard)"或"防止重复包含(Include Guard)"。它的作用是防止同一个头文件被多次包含导致的重定义错误。

  1. #ifndef ADDITION_H: 这是一个预处理器指令,意为 "if not defined",即如果宏 ADDITION_H 没有被定义过,则执行下面的代码。这里 ADDITION_H 是一个自定义的宏名称,通常会取和头文件名相关的名字。
  2. #define ADDITION_H: 这是另一个预处理器指令,用来定义宏 ADDITION_H。这样,当 ADDITION_H 被定义后,#ifndef ADDITION_H 就会失败,后面的代码将不会被包含。
  3. #endif: 这是一个预处理器指令,用来结束条件编译块。它表示着条件编译的结束。

这种写法的目的在于,当头文件被包含多次时,只有第一次包含时会真正将文件内容包含进去,后续的包含则会被预处理器忽略,从而避免了重定义错误。

这样的预处理器指令在大型项目中尤其有用,因为一个头文件可能会被多个源文件包含,如果没有适当的保护措施,就会导致重定义错误。


🌊2.2 头文件接口实现addition.cpp

addition.cpp内容如下:

#include "addition.h"
 
// 函数实现
int add(int a, int b) {
    return a + b;
}

通常头文件对应接口的实现命名与头文件类似,比如addition.cpp是头文件addition.h的接口实现。


🌊2.3 源文件

源文件调用头文件addition.h

#include <stdio.h>
#include "addition.h" // 包含头文件
 
int main() {
    int result = add(5, 3); // 调用add函数
    printf("Result: %d\n", result);
    return 0;
}


目录
相关文章
一键语法错误增强工具 ChineseErrorCorrector
【8月更文挑战第8天】ChineseErrorCorrector是一款实用的中文语法纠错工具,能迅速检测并修正文本中的语法错误,提升文本质量。其特点包括:1) 精准检测各种语法错误如词语搭配不当等;2) 提供详细错误解释及修改建议,助您学习语法规则;3) 快速高效地检查文本,适用于写作、编辑等场景。适合学生提高写作水平、商务文档的专业审阅、网络内容创作的质量把控以及翻译工作的校对等。总之,这款工具为中文文本提供了便捷高效的语法检查方案。
779 4
|
关系型数据库 MySQL 应用服务中间件
站库分离技术--反向代理技术-雷池云WAF-给自己搭建一个安全点的网站
站库分离技术--反向代理技术-雷池云WAF-给自己搭建一个安全点的网站
811 3
|
监控 算法 数据挖掘
HyperLogLog算法有哪些应用场景呢
【10月更文挑战第19天】HyperLogLog算法有哪些应用场景呢
309 0
|
设计模式 关系型数据库
设计模式的六大原则:理解设计模式的关键思想和应用
设计模式的六大原则:理解设计模式的关键思想和应用
473 2
|
机器学习/深度学习 Python
LightGBM高级教程:高级特征工程
LightGBM高级教程:高级特征工程【2月更文挑战第8天】
1296 2
|
数据采集 机器学习/深度学习 人工智能
|
机器学习/深度学习 缓存 人工智能
麻省理工提出“跨层注意力”,极大优化Transformer缓存
【7月更文挑战第4天】麻省理工学院的研究团队提出了一种新的Transformer优化技术——跨层注意力(CLA),旨在解决大型模型的缓存问题。CLA通过相邻层间共享键值头减半KV缓存,提高内存效率,允许处理更长序列和批量。实验显示,CLA在10亿至30亿参数模型中实现了性能与内存使用的良好平衡,但可能增加计算开销,并非所有模型适用。论文链接:[arXiv:2405.12981](https://arxiv.org/abs/2405.12981)
596 0
|
Shell 开发工具 Android开发
|
机器学习/深度学习 传感器 自动驾驶
探究自动驾驶技术:原理、概念
本文探讨了自动驾驶技术,其核心包括感知系统、数据处理与决策及控制系统。技术分为SAE定义的6个自动化级别,涉及规则与机器学习方法,以及车辆间通信。挑战包括安全性、法律道德问题和基础设施改造。未来,自动驾驶有望提升交通安全性、效率,改善出行体验并促进环保交通。