C语言为什么不支持函数重载?C和C++程序怎样互调?

简介: 笔记

在搞清楚这个问题之前,我们先弄清楚程序环境和预处理

1.png2.png


预编译阶段:生成test.i文件


编译阶段:test.i文件变为test.s文件,这个时候建立栈帧给局部变量开空间等等


汇编阶段:test.s文件变为test.o文件,符号表就是会给这些全局或函数变量一个地址


链接:将同一个项目下的.o文件合并,生成.exe文件 ,这个阶段会进行符号表的重定位(重新进行全局变量或函数的地址匹配)

3.png

解释C语言不能函数重载


4.png


在 linux系统下建立三个文件,用gcc运行会报错,而g++运行则不会

5.png

func.o文件里面是二进制机器码,只不过我们所看到的是一些汇编代码

6.png



在gcc下进行编译不能直接转换成对应的机器码。


每个.o文件最前面是与栈帧有关的一些东西,只不过是被转换成了机器码

7.png

而在函数调用的时候,要转换成一个汇编指令,这个汇编指令是call

8.png



call 一个地址,这个地址是jump指令的地址


函数地址是函数调用第一个指令的地址

9.png

06f5970h 才是函数地址


10.png


在main.o里面要调用函数,没有这俩个函数的地址 ,因为main.c文件里面只包含了.h文件(函数的声明),这个在编译阶段能过因为进行了声明,即使没有定义函数也能过,当执行call指令和jump指令时候,需要找到函数的第一句,即函数的定义,此时fun.c有函数的定义,而且有俩个


链接的工作:把.o目标文件合并到一起,还需要一些只给了声明的函数或变量的地址,如果找不到地址就会报链接错误,编译器会通过符号表寻找函数

11.png

C语言如果有俩个相同名字函数,则符号表会一样,这样导致在通过符号表找函数的时候就会出错


C++提出了函数名修饰规则

12.png

函数名是:函数名+参数类型首字母


i int d double


C语言的函数名修饰规则


函数名就直接是函数名,这会导致符号表在重新定位的时候会报错,所以会发生连接错误

13.png

C++调用C的库


C++程序可以调用C语言写的库,C语言也能调用C++写的库,但需要一些处理


把用C语言实现的栈转为静态库

14.png

新建一个C++项目。


用C++程序调用C的库,先包头文件,链接的时候才回去库中找程序

15.png

但此时会报错,我们用路径去包含

16.png

此时编译不会报错,但运行会报错,报连接错误,这是因为没有找到这些函数的定义,函数的定义我们刚才封装到了静态库中

17.png

接下来,我们把静态库加进去

18.png19.png

附加库目录输入.lib文件的目录


然后 切换到输入,附加依赖项

20.png

21.png

之后运行,仍然报错

22.png



这是因为我们用C++编译器找C的库, 函数修饰规则不一样


此时输入extern "C",并把包含的头文件给括起来

23.png



此时程序正常运行


extern"C"作用,告诉C++编译器,这里面的这些函数是C的库实现的,用C的规则去链接查找他们


C的程序调用C++库


24.png

把C++程序改成静态库


创建一个.C文件,之后跟上面做同样操作,引入静态库


25.png


此时,仍然会链接报错,接下来跟上面有点区别,不可能让C的编译器认识C++的库,只能修改C++的库,在C++的库加extern "C“,就是告诉编译器调用这些函数的时候按照C的规则来


但仍然会有一些问题,编译还会报错,这是因为C的编译器不认识extern ''C''

26.png



引入C++的宏去做条件编译,就能解决该问题  


相关文章
|
15天前
|
编译器 C语言 C++
C语言,C++编程软件比较(推荐的编程软件)
C语言,C++编程软件比较(推荐的编程软件)
|
3天前
|
C语言
第一章 C语言知识点(程序)
第一章 C语言知识点(程序)
14 0
|
11天前
|
存储 安全 编译器
【C++入门】缺省参数、函数重载与引用(下)
【C++入门】缺省参数、函数重载与引用
|
2天前
|
存储 自然语言处理 编译器
“ Hello world ”中的秘密之【C语言程序编译和链接】
作为C语言最经典的代码,大家都可以轻易写出。但是代码的运行过程却很少有人清楚,接下来我将介绍代码运行的奥秘。
13 0
|
4天前
|
自然语言处理 编译器 C语言
C语言程序编译和链接
在ANSI C的任何⼀种实现中,存在两个不同的环境。 第1种是翻译环境,在这个环境中源代码被转换为可执⾏的机器指令(⼆进制指令)。 第2种是执⾏环境,它⽤于实际执⾏代码。
|
6天前
|
网络协议 物联网 数据处理
【C 言专栏】C 语言实现网络通信程序
【5月更文挑战第4天】本文探讨了使用C语言实现网络通信程序的方法,包括理解网络通信基本概念如协议和套接字,以及TCP/UDP通信的实现步骤。通过创建套接字、绑定端口、监听连接、数据传输和错误处理等关键环节,阐述了C语言在网络通信中的优势。文中还提到了实际应用案例、程序优化策略及未来发展趋势,旨在帮助读者掌握C语言在网络通信领域的应用技巧。
【C 言专栏】C 语言实现网络通信程序
|
8天前
|
并行计算 算法 测试技术
【C 言专栏】优化 C 语言程序性能的策略
【5月更文挑战第2天】本文探讨了优化C语言程序性能的策略,包括算法优化(选择合适的时间和空间复杂度)、代码结构优化(减少函数调用,合理使用循环)、内存管理优化(合理分配和及时释放内存)、编译器优化(选择优化级别,内联函数,循环展开)、数据结构优化(根据需求选择数组、哈希表或堆)、并行计算优化(多线程、多进程和MPI编程)以及性能测试与分析(使用性能分析工具、基准测试和分析执行路径)。通过这些方法,可以提升C语言程序的效率和运行速度。
|
10天前
|
存储 Linux C语言
C语言进阶第十一节 --------程序环境和预处理(包含宏的解释)-2
C语言进阶第十一节 --------程序环境和预处理(包含宏的解释)
|
10天前
|
自然语言处理 Linux 编译器
C语言进阶第十一节 --------程序环境和预处理(包含宏的解释)-1
C语言进阶第十一节 --------程序环境和预处理(包含宏的解释)
|
11天前
|
编译器 C语言 C++
【C++入门学习指南】:函数重载提升代码清晰度与灵活性
【C++入门学习指南】:函数重载提升代码清晰度与灵活性
22 0