【C++初阶(二)】缺省参数以及函数重载(下)

简介: 【C++初阶(二)】缺省参数以及函数重载(下)

4. 几种不同类型的函数重载

总结三种支持函数重载的情况:

  1. 参数类型不同
int Add(int left, int right)
{
  return left + right;
}
double Add(double left, double right)
{
  return left + right;
}
  1. 参数个数不同
void f()
{
 cout << "f()" << endl;
}
void f(int a)
{
 cout << "f(int a)" << endl;
}
  1. 参数类型顺序不同
void f(int a, char b)
{
 cout << "杭州电子科技大学" << endl;
}
void f(char b, int a)
{
 cout << "圣光机联合学院" << endl;
}

(注意:下面这种不属于函数重载):

short Add(short x,short y)
{
  return x+y;
}
int Add(short x,short y)
{
  return x+y;
}

因为它们参数类型,数量,顺序都一样
只是返回值不同,不构成函数重载!


5. C++如何支持函数重载?

在C/C++中,一个程序要运行起来

需要经历以下几个阶段:

  • 预处理
  • 编译
  • 汇编
  • 链接

因为c++区别于c在这几个过程中

的差别,所以使C++能够支持函数重载


5.1 C程序为什么不支持函数重载?

定义两个源文件和一个头文件来解释:

  • func.h
  • func.c
  • main.c

在.h文件声明两个函数

int func(int x,int y);
int func(int x,double y);

这三个文件会经历以下过程:

  1. 预处理阶段

主要内容:头文件展开,宏替换
条件编译,去掉注释

这个过程结束后,func.h被展开了

main.c和func.c源文件变成了:

func.i和main.i文件

  1. 编译阶段

主要内容:语法检查和生成汇编代码

这个过程结束后,func.i和main.i

文件变成了func.s和main.s文件

(此文件中为汇编代码)

  1. 汇编阶段

主要内容:将汇编代码转换成二进制码
以便机器能够读懂

这个过程结束后,func.s和main.s

文件变成了func.o和main.o文件

注:前面的过程只用了解,真正的主角在下面!

  1. 链接过程
    func.o和main.o文件
    以及链接过程是这部分的重中之重

5.2 C程序的链接过程

func.c到func.o和main.c到main.o

都是单线程的

链接过程:

.o的目标文件会合并到一起
其次还需找一些只给了声明的函数
的函数地址

而每一个.o文件都有一个符号表

符号表中存放函数的地址

当main文件要调用这个函数时

会去符号表中找函数的地址

而符号表中两个func函数的地址
编译器不知道应该调用哪个
所以c程序不支持函数重载!


5.3 C++函数名修饰规则

相比起C程序而言,C++新增了一个
函数名修饰规则来支持函数重载

这个规则就是将函数的参数带入符号表
所以参数的类型,数量,顺序不同
代表的是不同的函数,找地址时就不会出错!

我们在C++的汇编代码中找到了
这两个函数对应的部分:

综上所述:

函数参数的类型,数量,顺序不同

那么对应在符号表中的名字就不一样

main文件再去找函数地址时就不会冲突

对比c程序:

c程序符号表中只有一个函数名
函数参数没有参与进来
所以C程序不支持相同函数名的函数


6. 总结以及拓展

前面很多过程只是为了
后面的链接.o文件打基础
所以前面的听不懂也没关系

只需要知道C++有函数名修饰规则
c++的.o文件的符号表的函数名
和函数参数相关
而c程序的符号表和参数无关!

拓展:

C/C++函数调用约定和名字修饰规则

有兴趣好奇的同学可以看看里面

有对vs下函数名修饰规则讲解

C/C++约定


🔎 下期预告:引用和内联函数 🔍


相关文章
|
6天前
|
编译器 程序员 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 变量的
13 4
C++函数重载
|
6天前
|
编译器 Linux C语言
【C++小知识】为什么C语言不支持函数重载,而C++支持
【C++小知识】为什么C语言不支持函数重载,而C++支持
|
11天前
|
安全 编译器 C++
C++入门 | 函数重载、引用、内联函数
C++入门 | 函数重载、引用、内联函数
18 5
|
11天前
|
编译器 C语言 C++
C++入门 | 命名空间、输入输出、缺省参数
C++入门 | 命名空间、输入输出、缺省参数
25 4
|
1月前
|
存储 自然语言处理 编译器
【C++入门 三】学习C++缺省参数 | 函数重载 | 引用
【C++入门 三】学习C++缺省参数 | 函数重载 | 引用
|
2月前
|
存储 编译器 C++
【C++ 初阶路】--- 类和对象(下)
【C++ 初阶路】--- 类和对象(下)
14 1
|
2月前
|
存储 编译器 C语言
【C++初阶路】--- 类和对象(中)
【C++初阶路】--- 类和对象(中)
20 1
|
1月前
|
算法 编译器 C++
C++基础知识(三:哑元和内联函数和函数重载)
在C++编程中,"哑元"这个术语虽然不常用,但可以理解为在函数定义或调用中使用的没有实际功能、仅作为占位符的参数。这种做法多见于模板编程或者为了匹配函数签名等场景。例如,在实现某些通用算法时,可能需要一个特定数量的参数来满足编译器要求,即使在特定情况下某些参数并不参与计算,这些参数就可以被视为哑元。
|
2月前
|
存储 编译器 C语言
【C++ 初阶路】--- 类与对象(上)
【C++ 初阶路】--- 类与对象(上)
18 0
|
6天前
|
C++ 容器
C++中自定义结构体或类作为关联容器的键
C++中自定义结构体或类作为关联容器的键
13 0