前言:
有几个问题:
1、为什么C不支持函数重载,C++支持函数重载?
2、既然C++可以支持函数重载,那么是如何支持的?
3、C能不能调用C++库?C++能不能调用C库?
本篇文章详细讲述上面问题
目录
1. C++支持函数重载的原因
对于本章的理解,得先知道编译链接的基本原理,在链接里面有详细的介绍。程序环境和预处理_玉兔阿离的博客-CSDN博客
在汇编阶段,还会生成符号表,在链接过程,会把所有源程序的符号表汇总,这个阶段就是函数能够实现重载的重要过程。
上图显示的是在C语言中,编译过程的符号表,函数名是没有被修饰的,函数名就是函数的原名,没有做出什么改变。
这张图是编译过程中,C++的符号表。可以明显的看出,函数名进行了修饰,本操作是在Linux环境下进行的,其他环境下函数名修饰另有法制。
-Z + 函数名长度 + 参数类型首字符
这就能解释为什么函数重载要求参数类型不一样了,只要参数类型不同,函数名就不同,就实现了重载。也可以看出实现函数重载和函数的返回值无关,不会影响到函数名的改变。
2. C能调用C++库吗?C++能调用C库吗?
先说答案,都是可以的。只不过在调用前要先进行处理,因为C和C++的语法不同,且有函数能否重载的因素,直接调用时,C++进行了函数没修饰,C找不到C++中的函数;同理,C没有进行函数名修饰,C++找不到C中的函数。
2.1 C++如何调用C库
具体是如何支持的呢
以栈为例,要先把栈实现成一个静态库
对于要调用栈的项目工程,也要进行处理,共两步操作
第一步:
第二步:
这时候,再包含头文件调用
因为头文件不在当前目录底下,这里需要相对目录,这里的 .. 就是找到上一层目录。每层目录中间隔一个 /
这就是C++调用C库的过程
2.2 C如何调用C++库
C调用C++库就有所不同了,操作更复杂一点,也是要先实现一个静态库,然后对调用库的工程项目进行那两步处理。不过在包含头文件时,不能再用extern "C"了。其一,这是C++的语法,C语言没有这个语法;其二,这句话的本意是告诉C++的编译器,要以C的方式去调用和链接这个库,如果用在C语言里,成了C告诉自己要以C的方式去调用和链接???岂不是很奇怪。
#ifdef __cplusplus #define EXTERN_C extern "C" #else #define EXTERN_C #endif EXTERN_C void StackInit(ST* ps); EXTERN_C void StackDestory(ST* ps); EXTERN_C void StackPush(ST* ps, STDataType x); EXTERN_C void StackPop(ST* ps); EXTERN_C bool StackEmpty(ST* ps); EXTERN_C int StackSize(ST* ps); EXTERN_C STDataType StackTop(ST* ps);
可以在头文件里面使用条件编译的方式。未调用时,在C++中,执行第一句指令,以C的方式去编译;当有C调用时,头文件展开包含,执行第二句指令,没有extern "C" ,编译器可以正常编译,达到想要的效果。
#ifdef __plusplus extern "C" { #endif void StackInit(ST* ps); void StackDestory(ST* ps); void StackPush(ST* ps, STDataType x); void StackPop(ST* ps); bool StackEmpty(ST* ps); int StackSize(ST* ps); STDataType StackTop(ST* ps); #ifdef __plusplus } #endif
或者也可以采用这种方式,和上面那种其实是一样的
3. 总结
C++支持函数重载的原因就在于在编译链接过程,采用一种特定的命名方式,进行了函数名的修饰。C和C++之间是可以相互调用的,只不过要做一点处理工作。