通常我们使用头文件时都是在头文件中进行声明,在源文件中定义,哪我们能否在头文件中进行函数的定义
  • 我们先进行一个测试,先声明一个test.h和一个test.cpp文件,并且在test.h中定义一个函数和一个变量

可以发现,程序运行没有问题,结果也正确

  • 再创建一个test.cpp文件,并且同时包含tset.h,再次运行

此时程序运行出错,提示出现了重定义的错误
可能有的同学会疑惑,不是已经使用了预处理指令来防止头文件重复包含了吗

#ifndef __TEST_H__
#define __TEST_H__
//头文件中的内容
#endif

使用此预处理指令的作用

防止头文件被重复包含,假如一个源文件中同时包含了头文件a和头文件b ,而头文件b中又包含a,哪在头文件展开时就会包含两份的头文件a,这样不仅浪费时间还降低了效率,而引入预处理指令就很好的解决了这个问题。

预处理的时间与范围

编译器在执行一个程序时大该分为以下几个步骤

预处理阶段:

预处理阶段是编译前的准备工作主要进行一下几个工作:

  • 执行预处理指令
  • 将头文件展开 即#include 所包含的内容
  • 进行宏替换
  • 删除注释
  • 添加行号和标识

注意:预处理阶段是各个源文件独自进行的,每个源文件互不干扰,预处理的作用范围仅在本文件中,在预处理完成后,会生成一个.i文件,而这个.i文件就是下一阶段编译时的一个编译单元,在此之后头文件就已经没有任何的作用了

编译

编译时是以编译单元为单位基本单位进行的,而编译单元即为预处理结束后每个.cpp 文件生成的.i 文件,编译时有以下工作

  • 函数和变量声明的检查
  • 语法分析 语义分析 词法分析 符号汇总等
  • 将代码转换为汇编语言

注意:编译时仅对函数和变量的声明进行检查,而不关心函数的定义,编译是以一个个单独的文件为单元的,与预处理一样,而这些编译单元都是之前生成的.i 文件。编译完成后会生成.s文件

汇编

将编译后生成的.s文件进行汇编

  • 转成机器指令
  • 生成符号表
  • 符号地址与地址重定位

在编译时会将地址用符号替代,编译器会将其翻译成虚拟地址
而地址的重定位就是建立物理内存与虚拟地址间的映射
在经过汇编阶段后,每个.s会生成一个对应的二进制的.o 文件

链接
  • 在编译完成后,生成了目标文件,此时就需要将这些目标文件链接起来生成可执行文的.exe件。
通过以上的编译器处理程序的过程,我们可以知道在链接之前,各个文件都是相互独立的,互不干扰。

此时,我们也就知道

  • 头文件是在预处理时起作用,而它的作用范围仅在当前文件
  • 编译时对于函数的定义并不关心,只关心声明,作用范围也仅在当前文件。
  • 而链接时才会将个个文件相互关联
那么之前的问题也就有答案了

因为在头文件中定义了一个函数,在预处理时头文件展开,每个文件都有了一个该函数的定义,因为编译时是分隔的,所以到链接时,将所有文件关联在一起时,发现每个包含了该头文件的文件中有一个相同函数的声明,编译器就会报出重定义的错误。

当只有一个源文件时,因为没有别的源文件的冲突所以不会报错

总结

  • 声明是在编译时处理
  • 定义是在链接时处理
  • 链接之前所有文件是隔离的

所以在头文件中尽量不要进行函数的定义,只对其进行声明。否则如果有多个源文件链接时会报错

头文件中能否进行函数的定义相关推荐

  1. C++STL中string的头文件中的常用函数

    文章目录 STL简介 头文件 初始化操作 实现效果 基本函数 1.size,length,capacity 2.resize,reserve 1,2的实现代码 实现效果 3.at,append,ins ...

  2. c语言头文件可以定义全局变量,C语言在头文件中定义全局变量

    C语言在头文件中定义全局变量 头文件定义全局变量等问题 全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么? 可以,在不同的C文件中以static形式来声明同名全局变量.头文件中不可以直接定 ...

  3. 将类的定义放在头文件中,把成员函数的实现代码放在一个cpp文件中

    将类的定义放在头文件中,把成员函数的实现代码放在一个cpp文件中 写这种.h和.cpp文件分开的大程序,虽然对很多人来说很简单,对自己来说算是第一次吧,好好学C++,加油~ 题目:定义Point类,由 ...

  4. [原创]Enterprise Architecture V7.5 C++代码生成时,头文件中函数声明没有注释,CPP中函数定义却有注释。...

    这几天一直在用Enterprise Architecture来抽象项目中要用到的一些数据结构和类,然后都做得差不多了之后发现,生成代码的时候.h文件中类成员函数部分没有注释,但是.cpp文件中的函数定 ...

  5. c语言头文件中定义inline static相关函数的优劣

    头文件中常见static inline函数,于是思考有可能遇到的问题,如头文件经常会被包含会不会产生很多副本?网上说法不一.于是自己验证.经过arm-none-eabi-gcc下测试后得出结论. in ...

  6. C语言中:在头文件中使用static定义变量意味着什么?

    C语言中:在头文件中使用static定义变量意味着什么? 看到有一位同学在头文件中这么写: static const wchar_t* g_str1 = - static const wchar_t* ...

  7. 将函数实现放在头文件中

    研究一个开源算法库,采用C++模板编程,所有函数实现都放在了头文件中,现在把模板去掉,链接时发生冲突,具体原因如下: 因为多个源文件包含了含有函数定义的头文件,在编译的时候,每个源文件都会包含一份函数 ...

  8. 能否用痰盂盛饭——谈谈在头文件中定义外部变量

    能否用痰盂盛饭--谈谈在头文件中定义外部变量 - garbageMan - 博客园 能否用痰盂盛饭--谈谈在头文件中定义外部变量 "能否用痰盂盛饭"并非是一个技术问题,而是一个哲学 ...

  9. 关于头文件中的 static inline函数

    关于头文件中的 static inline函数 头文件中常见static inline函数,于是思考有可能遇到的问题,如头文件经常会被包含会不会产生很多副本?网上说法不一.于是自己验证.经过arm-n ...

最新文章

  1. 根据函数指针地址获取函数名
  2. python进阶学啥书籍_2018年Python学习进阶书籍推荐
  3. 【Linux基础 11】vi和vim编辑器的使用
  4. 未来社区及其趋势探索
  5. 49 FI配置-财务会计-固定资产-与总账集成-分配总帐科目
  6. 关于django内置的ModelForm小记
  7. 图文详解什么是OAuth2
  8. ylbtech-dbs-m-YinTai(银泰网)
  9. lesson - 1 - IP /DNS /cat !$ /putty 知识扩充
  10. 一文带你读懂什么是vxlan网络
  11. ShxViewer_SHX字体查看
  12. 无约束多元函数求极值
  13. C语言中终端一直有光标闪烁,word里光标一直闪
  14. 计算机老师教师节祝福语,送给老师教师节祝福语
  15. 半导体储存器例题小试--十安辰
  16. 打开cmd的方式与常用的dos命令
  17. (三)大话深度学习编译器中的自动调优·Empirical Search
  18. 【SQL Server系列】_01数据库系统概述
  19. 基于二维码的设备巡检系统相关技术
  20. 自动驾驶企业Mobileye估值坍塌:降至160亿美元 路演PPT曝光

热门文章

  1. mysql练习题记录之:学生表、课程表、成绩表、讲师表、等级表
  2. 注册苹果开发者帐号 用什么银行的什么卡好? 收款帐号呢?
  3. 游戏防封技术是学易语言还是学c,易语言写游戏脚本防封执行sqlplus 之后没执行...
  4. .Net 中使用Farpoint Web Spread 自定义CellType
  5. 关于hi3516ev100调试zbar二维码和链接wifi问题
  6. HTTP状态码:400\500 错误代码(个人总结)
  7. MySQL数据库基础——数据库基础
  8. java dozer,MapStruct相当于提示(Dozer)?
  9. 青云很忙 QingCloud Insight 2017开幕倒计时
  10. 如何通俗易懂地解释卷积?