头文件中能否进行函数的定义
通常我们使用头文件时都是在头文件中进行声明,在源文件中定义,哪我们能否在头文件中进行函数的定义
- 我们先进行一个测试,先声明一个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件。
通过以上的编译器处理程序的过程,我们可以知道在链接之前,各个文件都是相互独立的,互不干扰。
此时,我们也就知道
- 头文件是在预处理时起作用,而它的作用范围仅在当前文件
- 编译时对于函数的定义并不关心,只关心声明,作用范围也仅在当前文件。
- 而链接时才会将个个文件相互关联
那么之前的问题也就有答案了
因为在头文件中定义了一个函数,在预处理时头文件展开,每个文件都有了一个该函数的定义,因为编译时是分隔的,所以到链接时,将所有文件关联在一起时,发现每个包含了该头文件的文件中有一个相同函数的声明,编译器就会报出重定义的错误。
当只有一个源文件时,因为没有别的源文件的冲突所以不会报错
总结:
- 声明是在编译时处理
- 定义是在链接时处理
- 链接之前所有文件是隔离的
所以在头文件中尽量不要进行函数的定义,只对其进行声明。否则如果有多个源文件链接时会报错
头文件中能否进行函数的定义相关推荐
- C++STL中string的头文件中的常用函数
文章目录 STL简介 头文件 初始化操作 实现效果 基本函数 1.size,length,capacity 2.resize,reserve 1,2的实现代码 实现效果 3.at,append,ins ...
- c语言头文件可以定义全局变量,C语言在头文件中定义全局变量
C语言在头文件中定义全局变量 头文件定义全局变量等问题 全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么? 可以,在不同的C文件中以static形式来声明同名全局变量.头文件中不可以直接定 ...
- 将类的定义放在头文件中,把成员函数的实现代码放在一个cpp文件中
将类的定义放在头文件中,把成员函数的实现代码放在一个cpp文件中 写这种.h和.cpp文件分开的大程序,虽然对很多人来说很简单,对自己来说算是第一次吧,好好学C++,加油~ 题目:定义Point类,由 ...
- [原创]Enterprise Architecture V7.5 C++代码生成时,头文件中函数声明没有注释,CPP中函数定义却有注释。...
这几天一直在用Enterprise Architecture来抽象项目中要用到的一些数据结构和类,然后都做得差不多了之后发现,生成代码的时候.h文件中类成员函数部分没有注释,但是.cpp文件中的函数定 ...
- c语言头文件中定义inline static相关函数的优劣
头文件中常见static inline函数,于是思考有可能遇到的问题,如头文件经常会被包含会不会产生很多副本?网上说法不一.于是自己验证.经过arm-none-eabi-gcc下测试后得出结论. in ...
- C语言中:在头文件中使用static定义变量意味着什么?
C语言中:在头文件中使用static定义变量意味着什么? 看到有一位同学在头文件中这么写: static const wchar_t* g_str1 = - static const wchar_t* ...
- 将函数实现放在头文件中
研究一个开源算法库,采用C++模板编程,所有函数实现都放在了头文件中,现在把模板去掉,链接时发生冲突,具体原因如下: 因为多个源文件包含了含有函数定义的头文件,在编译的时候,每个源文件都会包含一份函数 ...
- 能否用痰盂盛饭——谈谈在头文件中定义外部变量
能否用痰盂盛饭--谈谈在头文件中定义外部变量 - garbageMan - 博客园 能否用痰盂盛饭--谈谈在头文件中定义外部变量 "能否用痰盂盛饭"并非是一个技术问题,而是一个哲学 ...
- 关于头文件中的 static inline函数
关于头文件中的 static inline函数 头文件中常见static inline函数,于是思考有可能遇到的问题,如头文件经常会被包含会不会产生很多副本?网上说法不一.于是自己验证.经过arm-n ...
最新文章
- 根据函数指针地址获取函数名
- python进阶学啥书籍_2018年Python学习进阶书籍推荐
- 【Linux基础 11】vi和vim编辑器的使用
- 未来社区及其趋势探索
- 49 FI配置-财务会计-固定资产-与总账集成-分配总帐科目
- 关于django内置的ModelForm小记
- 图文详解什么是OAuth2
- ylbtech-dbs-m-YinTai(银泰网)
- lesson - 1 - IP /DNS /cat !$ /putty 知识扩充
- 一文带你读懂什么是vxlan网络
- ShxViewer_SHX字体查看
- 无约束多元函数求极值
- C语言中终端一直有光标闪烁,word里光标一直闪
- 计算机老师教师节祝福语,送给老师教师节祝福语
- 半导体储存器例题小试--十安辰
- 打开cmd的方式与常用的dos命令
- (三)大话深度学习编译器中的自动调优·Empirical Search
- 【SQL Server系列】_01数据库系统概述
- 基于二维码的设备巡检系统相关技术
- 自动驾驶企业Mobileye估值坍塌:降至160亿美元 路演PPT曝光
热门文章
- mysql练习题记录之:学生表、课程表、成绩表、讲师表、等级表
- 注册苹果开发者帐号 用什么银行的什么卡好? 收款帐号呢?
- 游戏防封技术是学易语言还是学c,易语言写游戏脚本防封执行sqlplus 之后没执行...
- .Net 中使用Farpoint Web Spread 自定义CellType
- 关于hi3516ev100调试zbar二维码和链接wifi问题
- HTTP状态码:400\500 错误代码(个人总结)
- MySQL数据库基础——数据库基础
- java dozer,MapStruct相当于提示(Dozer)?
- 青云很忙 QingCloud Insight 2017开幕倒计时
- 如何通俗易懂地解释卷积?