【C++入门篇—01函数重载的原理】

请添加图片描述



前言

本文总结学习C++小白篇—01函数重载的原理。


函数重载的原理

为什么C++支持函数重载,而C语言不支持

1.1 程序编译链接的原理

一个程序需要运行起来,需要经历:编译和链接两阶段。其中编译又可以具体分为预处理、编译、汇编

  1. 预处理阶段:将各个源.c文件单独处理,头文件的展开、条件编译、删除注释、宏替换,生成.i文件;
  2. 编译阶段:将各个.i文件单独处理,语法分析、词法分析、语义分析、符号汇总,把C/C++语言代码转换成汇编代码,生成.s文件
  3. 汇编阶段:将各个.s文件单独处理,把汇编代码转换成二进制指令,生成.o文件
  4. 链接阶段:将所有.o文件和链接库一起链接,主要进行:合并段表、符号表的合并和符号表的重定位,生成可执行文件。

1.2 结合函数重载分析

假设我们创建三个文件:

  1. 头文件f.h:函数f的声明
  2. 源文件f.c:包含头文件f.h,函数f的定义(void f(int num, char c))
  3. 源文件test.c:包含头文件f.h,调用函数f

1.2.1 预处理阶段

分别单独将源文件f.c 和 test.c进行:

  • 头文件f.h的展开

生成文件f.i 和 test.i

1.2.2 编译阶段

分别单独将文件f.i 和 test.i进行:

  • 把C/C++语言代码转换成汇编代码

文件f.i中,函数f变成了函数的各个指令
·
文件test.i中,因为该单独文件内没有函数f定义,只有声明,语法可以通过,但是该调用指令转变的汇编代码为:函数名(0X000…),不知道函数f的具体地址,赋为默认地址0X000…,等链接阶段,合并符号表时,会通过编译器对自己的函数名修饰规则的汇编代码中的函数名,来找对应该函数名的地址,然后链接在一起

  • 符号汇总
  • 检查语法:

1-f.i文件中:检查声明和定义是否匹配
2-test.i文件中:检查声明和函数调用是否匹配

注!!!
缺省参数必须在声明给,不能再定义给:
因为在编译阶段,在test.i文件中:检查声明和函数调用是否匹配时,如果声明未给缺省参数,且调用时使用缺省参数,则编译不通过。

生成文件f.s 和 test.s

1.2.3 汇编阶段

分别单独将文件f.s 和 test.s进行:

  • 把汇编代码转换成二进制指令

生成文件f.o 和 test.o(f.obj 和 test.obj)

1.2.4 链接阶段

整体将文件f.o 和 test.o(f.obj 和 test.obj)和链接库进行:

  • 合并段表
  • 符号表的合并
  • 符号表的重定位

文件test.o中生成的指令未包括函数f的地址,在此就在所有合并在一起的.o文件中,一个一个.o文件中找该函数名(编译器对自己的函数名修饰规则的汇编代码中的函数名)的地址,如果找到就链接到一起。
:如果在f.c文件中不放函数f的定义,则链接时,在各个.o
文件无法找到函数f的真正地址,只有之前的默认地址(或没有地址),从而报错:链接错误。

生成可执行文件


1.3 函数重载的原理

  • 在C语言编译器下:编译阶段将C代码转为汇编代码时,汇编代码的函数名就是原本C代码的函数名,本例中就是f
  • 在C++语言编译器下:编译阶段将C代码转为汇编代码时,汇编代码的函数名是特殊规则形成的,如果在linux下g++编译器下,汇编代码下函数命名规则为:

_Z 函数名长度 函数名 参数类型首字母
本例中就是_Z1fic

所以!!!

函数重载的原理就是:
C++编译器下,在编译阶段形成汇编代码时,函数名的汇编代码会根据特殊规则定义,而该特殊规则下:满足在函数重载的三种类型:1-参数个数不同;2-参数类型不同;3-参数类型的顺序不同下,函数名的汇编代码都不同,从而在链接阶段各自用不同的汇编函数名,去链接,匹配地址,不会出错。

而C语言下,显而易见,会报错。


总结

这里对文章进行总结:
以上就是今天总结的内容,本文包括了函数重载的原理,分享给大家。
真💙欢迎各位给予我更好的建议,欢迎访问!!!小编创作不易,觉得有用可以一键三连哦,感谢大家。peace
希望大家一起坚持学习,共同进步。梦想一旦被付诸行动,就会变得神圣。

欢迎各位大佬批评建议,分享更好的方法!!!🙊🙊🙊

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值