为什么C++支持函数重载

函数重载是C++的一个特性,允许在同一作用域内创建多个同名但参数不同的函数。文章通过示例展示了参数类型、数量和顺序不同的函数重载,并解释了C语言不支持函数重载的原因,主要在于C语言在编译阶段的符号表处理方式与C++不同。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C语言中我们知道创建的函数是不能同名的,但是在C++中却是可以的,这就是C++中的函数重载(函数名相同,参数列表不同),而函数重载有三种:函数参数类型不同、参数的数量不同、参数的顺序不同。所以就先浅浅的了解一下函数重载:

函数重载

参数类型不同

int Add(int a, int b)
{
	return a + b;
}
double Add(double a, double b)
{
	return a + b;
}
int main()
{
	int a1 = Add(3, 4);
	double a2 = Add(3.4, 4.3);
	cout << "a1 = " << a1 << endl;
	cout << "a2 = " << a2 << endl;

	return 0;
}

参数个数不同

int Add(int a, int b)
{
	return a + b;
}
double Add(double a, double b,double c)
{
	return a + b + c;
}
int main()
{
	int a1 = Add(3, 4);
	double a2 = Add(3.4, 4.3, 2.6);
	cout << "a1 = " << a1 << endl;
	cout << "a2 = " << a2 << endl;

	return 0;
}

参数顺序不同

double Add(int a, double b)
{
	return a + b;
}
double Add(double a, int b)
{
	return a + b;
}
int main()
{
	double a1 = Add(3, 4.3);
	double a2 = Add(3.2, 4);
	cout << "a1 = " << a1 << endl;
	cout << "a2 = " << a2 << endl;

	return 0;
}


double Add(int a, double b)
{
	return a + b;
}
double Add(double a, int b,double c)
{
	return a + b + c;
}
int main()
{
	double a1 = Add(3, 4.3);
	double a2 = Add(3.2, 4, 2.6);
	cout << "a1 = " << a1 << endl;
	cout << "a2 = " << a2 << endl;

	return 0;
}

其实像这种同时满足了上面的条件也是属于函数重载的,所以要发挥你的想象。

同时有一点极为重要:返回值类型不能作为重载依据。主要是针对返回值不同,参数列表一致的函数。因为在调用函数时,如果仅考虑函数调用表达式本身,编译器无法确定应该调用哪一个函数,因为可以忽略返回值(如func(1)这样的调用)

注:函数重载需在同意作用域内,可以不在同一个源文件下。

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

在C/C++中,一个程序要运行起来,需要经历以下几个阶段:预处理、编译、汇编、链接。C语言程序环境_c语言环境_小猴zhi永不言弃的博客-优快云博客可借鉴

  

C语言中会在编译阶段进行符号表汇总,就是记录在进入主函数之前所创建的全局变量和函数名这些数据。

在汇编阶段就会将这些数据存在符号表当中,并且每个数据都对应着各自的地址(对于函数而言:地址是在函数定义时才会出现,即形成汇编代码时的第一句指令所在的地址就是该函数符号的地址)

寻址的步骤是在链接阶段。链接时,编译器将所有源文件的符号表进行合并最终还在链接阶段将这些符号表合并与重定位,也就是将那些具有相同符号名的数据地址进行合并成一个有效的地址符号名。

所以话说回来,在C语言当中如果遇到同名函数(函数重载)时,在在编译阶段的语法分析阶段时就会出错,将两个同名的函数放到符号表,生成相对应的地址,而且地址还不相同,最后进行符号表汇总时就会出现问题。

编译后函数名变化只是在原来的函数名前加了一个下划线,所以当同名的函数参数不同时,编译器无法解析到他们的不同,因为它们编译后的名称都相同,所以C语言不能函数重载


C++其实和C语言经历的阶段是相同的,但是C++在这里做了优化的,在编译阶段时也是进行相同的符号表汇总,但是函数重载在C++中并不是看作相同符号名的函数,而是视作不同符号名的函数,所以这里C++是引入了函数名修饰规则

而函数名修饰就是将你所生成符号表时的函数名进行一定的修改,而C语言对于函数名修饰就是加一个下滑杠_,而C++就比较复杂,不同编译器的函数名修饰出来的效果也都不相同。

 VS中MSVC 编译器对同一个函数名(func)的修饰:(HN交换了位置)

而gcc编译器对函数名的修饰是:_Z + 函数名长度 + 函数名 + 参数类型的缩写。比如,

int Add(int a, double b)就变成了_Z3Addid

所以回到问题,C语言不支持函数重载的原因:

  • C 语言编译器在编译时,是通过函数名来识别函数的,不会去考虑参数类型、参数个数这些特征,只要函数名相同就认为是重复定义,而函数重载需要依靠不同的参数列表(参数个数、参数类型等不同)来区分同名函数,这一点 C 语言机制不支持。
  • C 语言没有像 C++ 那样的函数名修饰机制,C++ 中编译器会根据函数的参数等情况对函数名进行修饰,使得同名但参数不同的函数最终有不同的内部标识,而 C 语言不存在这样的处理,所以无法实现函数重载。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CR0712

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值