C语言不支持重载,但C++支持函数重载的原因

在解释原因之前,我们首先需要了解一些基本知识

1、什么是重载??

重载:函数名相同时,参数类型、参数个数、参数顺序,三者任意一者不同即可构成重载

2、程序运行时干了啥?——以func.h为例

程序运行起来需要经过下面几个阶段:

(1)预处理 —— 头文件展开、宏替换(#define)、条件编译(#ifdef)、去除注释(生成 .i 文件)

(2)编译 —— 检查语法,若无误,生成汇编代码(生成 .s文件)

(3)汇编 —— 汇编代码转换成二进制机器码(生成 .o文件)

(4)链接 —— 生成可执行文件

 

在预处理阶段,展开头文件func.h,将函数声明裸露在main函数中(后面通过实例说明)

在编译阶段,检查语法,C和C++根据各自的编译命名规则生成 对应的函数名

在汇编阶段,生成 func.o文件以及func.o的符号表(编译阶段生成的函数名:函数地址)

在链接阶段,根据编译阶段生成的函数名 去符号表找  函数地址,以此找到函数定义     

3、C 和 C++ 在编译时 生成函数名的编译规则??

C编译规则:  直接使用函数名

                      func(int x) =======》  编译后生成的函数名:func

                       符号表     =======》  func:4500232

C++编译规则: _Z + 函数名长度 + 函数名 + 形参类型

                      func(int x) =======》  编译后生成的函数名:_Z4funci

                      符号表     =======》  _Z4funci:4500232

编译生成汇编代码的过程中,C和C++对函数的处理就体现出来了

下面将在Linux系统上分析,因为Linux上的函数名修饰规则比较 清晰


目录

一、准备工作

二、原理解析

 三、C 测试

(1)单个函数

(2)多个同名函数

四、C++测试

(1)新增重载函数

 (2)程序测试

五、总结


一、准备工作

在Linux中新建func.h 、func.c、test.c文件

 

 编译生成 .out文件(等价于windows下的exe文件)

二、原理解析

预处理 =======》展开 func.h,func.h中的函数声明和main函数在同一个文件中          

                           

汇编    =======》 检查是否有语法错误,如果是C 编译,则按照C的规则生成 汇编函数名

                                                                  如果是C++编译,则按照C++的规则生成 汇编函数名

编译    =======》  生成二进制机器码,即.o文件(计算机只能识别二进制机器码)

                                生成func.o的时候,会顺带一个符号表

链接   =======》 C程序:call func(?),根据 func 去符号表找函数地址,执行函数体

                              C++:call  _Z4funci(?),根据 _Z4funci 去符号表找函数地址,执行函数体

PS:

(1)call  是汇编语言中调用函数的指令,存在于.s文件中,这里意为调用func函数

(2)  func(?) —— 调用函数的时候只知道函数名,但不知道函数地址

                             在符号表中找到对应的函数地址以后, ?会被替换为函数地址,如  func(40052d)

                               

 三、C 测试

(1)单个函数

在Linux命令行输入 objdump -S ./a.out

调用函数时,执行指令 call <func

===>C程序调用函数时,也就是链接阶段,直接通过 函数名 去找 函数地址,不考虑参数个数或者参数类型

(2)多个同名函数

假设我们又定义了一个 func(int a) ,

函数调用的时候,都是 call func(?),在符号表中有两个 func ,C 程序不知道要调用哪个函数

所以就会报错

四、C++测试

(1)新增重载函数

我们在原本的基础上新增一个函数

 

 

 (2)程序测试

 我们会发现,汇编使用的函数名,不是一样的!!

C++有自己的名字修饰规则:_Z + 函数名长度 + 函数名 + 形参类型

 call 指令会根据 修饰后的函数名 去符号表找 函数地址,然后通过函数地址链接到对应的函数定义

 找到 函数地址 后,把 ?换掉

五、总结

C语言:直接根据  函数名  去符号表找函数地址

C++:有自己的修饰规则,能够根据  修饰后的函数名  映射到地址

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值