函数重载你真的了解吗?

函数重载你真的了解吗?在 C 语言中 函数名修饰是相对较简单的 因为 C 语言本身不支持函数的重载

大家好,欢迎来到IT知识分享网。

1.什么叫函数重载?

函数重载(Function Overloading)是指在同一个作用域内,允许定义多个具有相同名称但参数列表不同的函数。具体而言,函数重载允许你定义同名的函数,但这些函数应该有不同的参数类型、参数个数或者参数顺序。

举例

函数重载你真的了解吗?

上述代码中有两个名为Print的函数,虽然名字一样,但是参数类型不一样。在c语言中会认为这两个是一个函数,后一个定义的会覆盖前面一个。在c++中函数重载的概念引入之后便认为这两个函数是不同的两个函数,并会根据传参类型自动选择相应的函数,由此一来我们的代码会变得更加灵活和易读

2.参数不同构成函数重载

函数重载你真的了解吗?

值得注意的是,如果仅仅是函数返回值不同是无法构成函数重载的。在函数调用时,编译器会根据实际传递的参数类型来确定调用哪个函数,而不是仅仅依赖于返回值类型。

函数重载你真的了解吗?

函数重载你真的了解吗?

3.函数重载的原理

为什么c语言不支持函数重载而c++支持呢?

在c/c++中,一个程序要想运行起来需要经历以下几个阶段:预处理、编译、汇编、链接。

预处理会将.c/.cpp文件中的代码经过头文件展开、去除注释、宏替换、条件编译转换成 .i文件

编译会将 .i 文件中的代码翻译成汇编代码,生成 .s文件

汇编会将 .s中的汇编代码翻译成二进制指令,生成 .o文件(也叫目标文件)

链接会将程序所有的 .o 文件进行链接生成 .exe后缀的可执行文件

各个阶段具体是怎么实现的可以去看

c语言的程序环境和预处理(一眼丁真)_c语言环境打击那-CSDN博客

其中,在链接这个阶段会进行合并段表、符号表的合并和符号表的重定位等行为。简单来说,链接操作通过合并这些符号表等实现了程序中各个文件的连接,也就是能在一个文件中通过符号表找到另一个文件定义的函数地址并执行这个函数。 

4.函数名修饰规则

函数名修饰(Name Mangling)通常是指编译器对函数名进行的一些变换或修改,以便区分同名函数或支持函数的重载。在C语言中,函数名修饰是相对较简单的,因为C语言本身不支持函数的重载。

4.1对比c/c++处理函数名

C语言中的函数名不会被修饰: 在C语言中,函数名不会被编译器修改或添加任何前缀或后缀,因为C语言本身不支持函数的重载。因此,C语言的函数名在源代码中的写法和编译后的二进制代码中是一样的。

C++语言中的函数名修饰: C++支持函数的重载,因此编译器需要在编译阶段对函数名进行修饰,生成唯一的函数名以区分不同的函数。修饰的方式通常包括添加函数参数类型参数个数等信息。

4.2c++具体是怎么修饰函数名的呢?

以linux举例,在Linux中,g++ 编译器使用 C++ ABI (Application Binary Interface) 标准,其函数名修饰规则是按照 Itanium C++ ABI 来进行的。以下是一些基本规则:

  1. 函数名修饰格式: C++ 编译器根据函数的参数类型、参数个数、以及一些其他信息生成一个唯一的函数名。这个过程称为 name mangling。修饰后的函数名通常包含原函数名以及一些用于标识参数类型和个数的信息。
  2. 名称修饰的参数类型表示: 常见的参数类型表示包括基本数据类型、指针、引用等。例如,int 类型可能用 i 表示,double 类型可能用 d 表示。
  3. 参数个数和其他信息: 修饰还包括参数的个数和其他一些信息,以区分函数重载和模板特化等情况。

观察以下函数

void myFunction(int x, double y);//修饰后的函数名为:_Z10myFunctionid

g++编译器对该函数名修饰后变成了_Z10myFunctionid,在这个例子中,_Z10 是由编译器添加的前缀(不同编译器可能不一样),myFunction 是原函数名,后面的 id 表示参数的类型,i 表示 int 类型,d 表示 double 类型。

4.3用汇编代码查看函数名是否被修饰 

观察以下代码

函数重载你真的了解吗?

以上代码是在linux中的vim编译器运行的,具体的操作指令大家无需了解。我们只需要知道gcc是编译c语言的编译器,而g++是编译c++代码的编译器。我们现在用两种方式去编译同一份代码,并观察其 汇编阶段生成的 .s 文件,这样我们就能在汇编层面观察到函数名被修饰的样子。

用gcc编译

函数重载你真的了解吗?

用g++编译 

函数重载你真的了解吗?

我们可以看到,add函数名被修饰成了_Z3addii 其中后缀”ii” 指的是两个参数的类型。这样一来,两个函数的名字名即使相同,我们也能因为其参数不同生成两个不同的“函数名”。

5.总结

通过这里就理解了C语言没办法支持重载,因为同名函数没办法区分。而C++是通过函数修
饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载

同时需要注意的是,函数名修饰的具体的修饰规则可能会因编译器版本、编译选项、操作系统等因素而有所不同。在实际的应用中,除非涉及到与其他语言或库的交互,否则大多数情况下不需要深入了解或处理函数名修饰。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/130825.html

(0)
上一篇 2025-08-12 17:20
下一篇 2025-08-12 17:26

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信