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++的宏去做条件编译,就能解决该问题  


相关文章
|
2月前
|
存储 算法 C语言
"揭秘C语言中的王者之树——红黑树:一场数据结构与算法的华丽舞蹈,让你的程序效率飙升,直击性能巅峰!"
【8月更文挑战第20天】红黑树是自平衡二叉查找树,通过旋转和重着色保持平衡,确保高效执行插入、删除和查找操作,时间复杂度为O(log n)。本文介绍红黑树的基本属性、存储结构及其C语言实现。红黑树遵循五项基本规则以保持平衡状态。在C语言中,节点包含数据、颜色、父节点和子节点指针。文章提供了一个示例代码框架,用于创建节点、插入节点并执行必要的修复操作以维护红黑树的特性。
68 1
|
2月前
|
NoSQL 编译器 程序员
【C语言】揭秘GCC:从平凡到卓越的编译艺术,一场代码与效率的激情碰撞,探索那些不为人知的秘密武器,让你的程序瞬间提速百倍!
【8月更文挑战第20天】GCC,GNU Compiler Collection,是GNU项目中的开源编译器集合,支持C、C++等多种语言。作为C语言程序员的重要工具,GCC具备跨平台性、高度可配置性及丰富的优化选项等特点。通过简单示例,如编译“Hello, GCC!”程序 (`gcc -o hello hello.c`),展示了GCC的基础用法及不同优化级别(`-O0`, `-O1`, `-O3`)对性能的影响。GCC还支持生成调试信息(`-g`),便于使用GDB等工具进行调试。尽管有如Microsoft Visual C++、Clang等竞品,GCC仍因其灵活性和强大的功能被广泛采用。
95 1
|
2月前
|
C++
C++ 根据程序运行的时间和cpu频率来计算在另外的cpu上运行所花的时间
C++ 根据程序运行的时间和cpu频率来计算在另外的cpu上运行所花的时间
34 0
|
2月前
|
编译器 C语言 计算机视觉
C语言实现的图像处理程序
C语言实现的图像处理程序
78 0
|
10天前
|
C++
【C++基础】程序流程结构详解
这篇文章详细介绍了C++中程序流程的三种基本结构:顺序结构、选择结构和循环结构,包括if语句、三目运算符、switch语句、while循环、do…while循环、for循环以及跳转语句break、continue和goto的使用和示例。
14 2
|
17天前
|
算法 机器人 C语言
ROS仿真支持C++和C语言
ROS仿真支持C++和C语言
28 1
|
28天前
|
存储 编译器 程序员
C语言程序的基本结构
C语言程序的基本结构包括:1)预处理指令,如 `#include` 和 `#define`;2)主函数 `main()`,程序从这里开始执行;3)函数声明与定义,执行特定任务的代码块;4)变量声明与初始化,用于存储数据;5)语句和表达式,构成程序基本执行单位;6)注释,解释代码功能。示例代码展示了这些组成部分的应用。
41 10
|
1天前
|
程序员 C++ 开发者
C++入门教程:掌握函数重载、引用与内联函数的概念
通过上述介绍和实例,我们可以看到,函数重载提供了多态性;引用提高了函数调用的效率和便捷性;内联函数则在保证代码清晰的同时,提高了程序的运行效率。掌握这些概念,对于初学者来说是非常重要的,它们是提升C++编程技能的基石。
5 0
|
2月前
|
编译器 程序员 C语言
C++函数重载
在实际开发中,有时候我们需要实现几个功能类似的函数,只是有些细节不同。例如希望交换两个变量的值,这两个变量有多种类型,可以是 int、float、char、bool 等,我们需要通过参数把变量的地址传入函数内部。在C语言中,程序员往往需要分别设计出三个不同名的函数,其函数原型与下面类似: void swap1(int *a, int *b); //交换 int 变量的值 void swap2(float *a, float *b); //交换 float 变量的值 void swap3(char *a, char *b); //交换 char 变量的
18 4
C++函数重载
|
1月前
|
编译器 C语言 C++
从C语言到C++
本文档详细介绍了C++相较于C语言的一些改进和新特性,包括类型检查、逻辑类型 `bool`、枚举类型、可赋值的表达式等。同时,文档还讲解了C++中的标准输入输出流 `cin` 和 `cout` 的使用方法及格式化输出技巧。此外,还介绍了函数重载、运算符重载、默认参数等高级特性,并探讨了引用的概念及其应用,包括常引用和引用的本质分析。以下是简要概述: 本文档适合有一定C语言基础的学习者深入了解C++的新特性及其应用。
下一篇
无影云桌面