C语言为什么不支持函数重载_c++又是如何支持的

在这里插入图片描述

什么是函数重载

函数重载是函数的一种特殊情况:
C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题

我们会有很多的场景使用函数重载, 比如我们想写一个Add(), 可以浮点,也可以整数, 但是又不想改变函数的名字,就可以用到函数的重载,根据 传入的参数让编译器去判断使用哪个函数
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这就是函数重载的简单使用

函数重载的注意事项
与缺省参数

有很多人会问, 缺省参数和函数重载在一起的时候,比如这样
在这里插入图片描述

f(1);  

这样调用的到底是第一个呢,还是第二个呢,
事实上编译器是不允许这样的,因为不知道你调用的是哪个,你如果传2个参数,那会去调用下面那个,你如果传一个参数,就会报错

返回值不同是不是函数重载

在这里插入图片描述

如果我们去调用

f(10) ;
f(20);
编译器如何知道你想使用的是哪个??? 不管有没有返回,都无法区别

所以,返回值不同,不构成函数重载

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

在C/C++中,一个程序要运行起来,需要经历以下几个阶段:预处理、编译、汇编、链接

预处理

  • 宏替换
  • 注释替换
  • 条件编译
  • 头文件展开

编译

  • 检查语法 语义
  • 讲C代码转换为汇编代码

汇编
把汇编代码转换为二进制代码
生成符号表
链接

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

简单说明一下这些,大家都知道,我们在调用一个函数的时候,如果函数定义不在前面,那么需要声明,不然就会error

如果当前文件只有函数的声明,那么编译器就会在链接的时候去其他文件对应生成的符号表去找函数的地址
在这里插入图片描述

如果找不见,报的错误是LNK ,就是link错误, 链接器没有找到

可以看到 函数的名字被解析成了 _f

在Linux下,使用gcc编译
在这里插入图片描述

调用执行过程如图,C是通过函数名字去其他符号表中寻找地址的
在这里插入图片描述

如果C语言支持函数重载
在这里插入图片描述

这该如何确定? 一个名字对应多个地址?? 就有了二义性,冲突

C语言不支持函数重载,因为编译的时候,两个重载函数,函数名相同,在func.o 中的符号表中表示歧义,链接的时候也存在冲突,所以不支持

C++ 是如何支持函数重载的

前面说了,C语言不支持重载的原因就是它用函数名来标识, 那么C++支持函数重载,说明一定不是用函数名来标识,那具体是怎么表示的呢?
在这里插入图片描述

这里使用g++在centos下编译 , 得到a.out,然后使用objdump工具查看

链接的时候使用修饰后的函数名进行查找,

在g++函数修饰规则是否是那样的呢?再来验证一下
在这里插入图片描述

总结

  1. C语言不能重载的原因主要是使用函数名去符号表中查找,而函数重载函数名一定是相同的
  2. C++引入了函数名修饰规则,用修饰过的函数名去符号表中匹配或者查找,保证不冲突,
  3. 在g++中,函数名修饰规则是, _Z + 函数名长度+ 函数名+ 参数类型首字母
    在这里插入图片描述
  • 26
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 18
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值