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;
}
其实像这种同时满足了上面的条件也是属于函数重载的,所以要发挥你的想象。
为什么C语言不支持函数重载C++可以
在C/C++中,一个程序要运行起来,需要经历以下几个阶段:预处理、编译、汇编、链接。C语言程序环境_c语言环境_小猴zhi永不言弃的博客-CSDN博客可借鉴
C语言中会在编译阶段进行符号表汇总,就是记录在进入主函数之前所创建的全局变量和函数名这些数据。
在汇编阶段就会将这些数据存在符号表当中,并且每个数据都对应着各自的地址(对于函数而言:地址是在函数定义时才会出现,即形成汇编代码时的第一句指令所在的地址就是该函数符号的地址)
寻址的步骤是在链接阶段。链接时,编译器将所有源文件的符号表进行合并最终还在链接阶段将这些符号表合并与重定位,也就是将那些具有相同符号名的数据地址进行合并成一个有效的地址符号名。
所以话说回来,在C语言当中如果遇到同名函数(函数重载)时,在编译时就会出错,将两个同名的函数放到符号表,生成相对应的地址,而且地址还不相同,最后进行符号表汇总时就会出现问题。
编译后函数名变化只是在原来的函数名前加了一个下划线,所以当同名的函数参数不同时,编译器无法解析到他们的不同,因为它们编译后的名称都相同,所以C语言不能函数重载
C++其实和C语言经历的阶段是相同的,但是C++在这里做了优化的,在编译阶段时也是进行相同的符号表汇总,但是函数重载在C++中并不是看作相同符号名的函数,而是视作不同符号名的函数,所以这里C++是引入了函数名修饰。
而函数名修饰就是将你所生成符号表时的函数名进行一定的修改,而C语言对于函数名修饰就是加一个下滑杠,而C++就比较复杂,不同编译器的函数名修饰出来的效果也都不相同。
VS中对同一个函数名(func)的修饰:(HN交换了位置)
而Linux对函数名的修饰是:_Z + 函数名长度 + 函数名 + 参数类型的缩写。比如,
int Add(int a, double b)就变成了_Z3Addid