1、概念
- 是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数
- 要求:这些同名函数的形参列表(①参数个数 或 ②参数类型 或 ③参数类型顺序–>不同类型)不同
- 作用:处理实现功能类似数据类型不同的问题。
2、函数重载的意义:方便,像是同一个函数一样
- ①相同功能函数(但传入不同类型参数)能用起来像同个函数
- ②自动识别类型其实也是利用了函数重载
//void Swapi(int* p1, int* p2)--->C语言不支持函数重载,只能写不同函数
void Swap(int* p1, int* p2)
{
int tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
//void Swapd(double* p1, double* p2)--->C语言不支持函数重载,只能写不同函数
void Swap(double* p1, double* p2)
{
double tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
//
//int main()
//{
// int a = 1, b = 2;
// double c = 1.1, d = 2.2;
// Swap(&a, &b);//意义①:但这样看起来就像同个函数一样
// Swap(&c, &d);
//
// cout << a;//意义②
// cout << c;
//
//
// return 0;
//}
3、C++支持函数重载的原理–名字修饰(name Mangling)
- 为什么C++支持函数重载,而C语言不支持函数重载呢?
- ①关于程序运行几个阶段:
- 预处理:头文件展开、宏替换、条件编译、去掉注释
- 翻译:语法检查、生成汇编代码
- 汇编:把汇编代码转换二进制机器码
- 链接:把.o的目标文件合并到一起;其次还需要找一些只给声明函数变量地址(若仅有声明找不到定义,就会报链接错误。)
- 最后生成:a.out ; xxx.exe
- ②左边func.c编译可直接转换成对应的汇编指令,右边main.c函数转换不出来为什么?
- 两边都是函数都要建立栈帧的代码,但main函数中要调用函数–> call 函数,此时就需要根据对应声明找函数了。
- 每个.o文件都可能包含有很多函数,故此时都记录在符号表中。
- 符号表:每个.o都会配一个符号表,链接的时候根据符号表中记忆的函数地址去找。
- ③总结回答:
- C语言不支持函数重载,是因为C语言是直接用函数名填到符号表里了,以根据函数名找地址,而符号表中记录的是同样的函数名,即使地址不同也无法区别、不知道去找谁。
- 而C++中为了支持函数重载,就提出了函数名修饰规则–>【如下:_z是前缀,4表函数名共四个字符,id表参数类型首字母(int,double)】
4、extern “C”
① C++的程序调用C的静态库
- C++的编译器和C的编译器编译完生成的内容都是二进制的指令,它们都能合并到一起的,除了语法上的细节规则有所不同,但最终合成的都是二进制的指令(都是给CPU看的),链接唯一障碍就是函数名修饰规则。
- 在C++中extern"C"作用:告诉c++的编译器,这里面的这些函数是C的库实现的,你用C的规则去链接查找它们
② C的程序调用C++的静态库
- 还是只能修改C++,但extern是cpp中才能看得懂,c无法使用,
- 可以通过添加宏
#ifdef _cplusplus
后,再使用extern "C"这样就能被识别了
祝大家学习愉快: )