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

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:C++初阶之路⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你学习排序知识
  🔝🔝


在这里插入图片描述

缺省参数&函数重载

  • 1. 前言
  • 2. 缺省参数
    • 2.1 全缺省
    • 2.2 半缺省
  • 3. 函数重载概念
  • 4. 几种不同类型的函数重载
  • 5. C++如何支持函数重载?
    • 5.1 C程序为什么不支持函数重载?
    • 5.2 C程序的链接过程
    • 5.3 C++函数名修饰规则
  • 6. 总结以及拓展

1. 前言

写C语言代码的时候
特别是在写数据结构时:

经常忘记传函数的参数
或者当前不需要什么参数

C++增加了缺省参数来解决这个问题

而为了解决相似功能的函数的函数名问题

C++增加了函数重载来解决这个问题

本篇文章将简单介绍缺省参数
并着重讲解函数重载的底层原理!

在这里插入图片描述


2. 缺省参数

缺省参数是声明或定义函数时
为函数的参数指定一个缺省值
在调用该函数时,
若没有指定实参
则采用该形参的缺省值
否则使用指定的实参

缺省参数分类:

  1. 全缺省
  2. 半缺省

2.1 全缺省

类似于这样的代码:

void Func(int a = 10, int b = 20, int c = 30){cout<<"a = "<<a<<endl;cout<<"b = "<<b<<endl;cout<<"c = "<<c<<endl;}

全缺省指的是函数的所有参数都给缺省值

有四种调用此函数的方式:

  1. 什么都不传:
Func();

此时系统默认a,b,c的值分别为
10 - 20 - 30

  1. 只传一个参数:
Func(15);

此时,a的值为15
而系统默认b,c的值为
:20-30

  1. 传两个参数:
Func(15,25);

此时a,b的值为:15 - 25
系统默认c的值为30

  1. 三个参数都传:
Func(15,25,35);

此时a,b,c的值为:15-25-35


注意: 传参不能写成这种形式:

Func(,25,);
Func(,,35);
Func(,25,35);
Func(15,,35);

2.2 半缺省

半缺省类似于这种形式:

void Func(int a, int b = 10, int c = 20){cout<<"a = "<<a<<endl;cout<<"b = "<<b<<endl;cout<<"c = "<<c<<endl;}

只要有参数没有给缺省值
那么它就是半缺省的

注意:

  1. 半缺省参数必须从右往左依次来给出,不能间隔着给
  2. 缺省参数不能在函数声明和定义中同时出现
  3. 缺省值必须是常量或者全局变量

比如下面这样定义半缺省是不行的:

void Func1(int a=10,int b,int c);
void Func2(int a,int b=20,int c);
//有缺省值的前提是它的右边的参数都有缺省值

3. 函数重载概念

以前有一个笑话:国有两个体育项目大家根本不用看,也不用担心。一个是乒乓球,一个
是男足。前者是“谁也赢不了!”,后者是“谁也赢不了

这里使用了一语双关.
而函数重载的概念和它类似:

函数重载是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。

举个例子:

void func(int i,char ch) //函数1
{//...
}void func(char ch,int i) //函数2
{//...
}

函数1和2可以同时存在
并且它们不是同一个函数


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++约定


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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/5291.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python学习——函数

一、函数的定义 函数就是执行特定任务和完成特定功能的一段代码。使用函数可以对代码进行复用&#xff0c;提高代码的可维护性和可读性&#xff0c;使得程序便于调试。 二、函数的创建 创建格式 #创建和格式 def 函数名&#xff08;[参数]&#xff09;:函数体[return xxx]举例…

MySQL:库的操作和表的操作(内含MySQL数据类型讲解)

进入数据库的数据目录 cd var/lib/mysql 库的操作 创建数据库 创建数据库的本质是创建目录。 创建数据库时有两个编码集&#xff1a;1.数据库编码集&#xff08;存储时使用&#xff09;2.进行字段比对读取时使用的编码方式&#xff09; 语法&#xff1a; CREATE DATABASE …

7、Redis复制(replica)

Redis复制(replica) 是什么&#xff1f; 就是主从复制&#xff0c;master以写为主&#xff0c;Slave以读为主。当master数据变化的时候&#xff0c;自动将新的数据异步同步到其它slave数据库 读写分离 容灾恢复 数据备份 水平扩容支撑高并发 案例演示 架构说明 一个Master两个…

微服务系列文章之 seata 事务模式

XA模式 XA 规范 是 X/Open 组织定义的分布式事务处理&#xff08;DTP&#xff0c;Distributed Transaction Processing&#xff09;标准。 XA 规范 描述了全局的TM与局部的RM之间的接口&#xff0c;几乎所有主流的数据库都对 XA 规范 提供了支持。 两阶段提交 XA是规范&…

深度学习优化算法

梯度下降算法 随机梯度下降。随机梯度下降是指每次迭代在训练数据中随机抽取一个数据计算梯度来更新模型得参数。随机梯度下降容易受到噪声干扰,训练时间长,代价函数最终会围绕全局最小值或者局部极小值震荡。批量梯度下降。每次迭代时使用所有的训练数据来计算梯度更新模型的…

UE5 录制透明png序列帧

以下是在 Unreal Engine 5 中录制透明 PNG 序列帧的详细步骤&#xff1a; 步骤1&#xff1a;创建一个场景 步骤2&#xff1a;打开序列录制器 在 Unreal Engine 5 中&#xff0c;首先需要打开序列录制器。你可以通过点击顶部菜单栏的 窗口 > 开发人员工具 > 序列录制器 …

WEB漏洞-XXEXML之利用检测绕过全解(39)

#概念 xml&#xff1a;xml被设计成传输和储存数据&#xff0c;XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素&#xff0c;其焦点是数据的内容。就类似于一种数据的格式&#xff0c;代码类的一些东西&#xff1b; xxe&#xff1a;是xml上面的一个漏洞&#xff0c;…

mesh网格数据解析及cesium绘制格网三角网可视化实现

代码实现运行效果 技术术语 Mesh通常指网络拓扑中的网状结构。在计算机网络中&#xff0c;Mesh是指每个节点都与其他节点相连&#xff0c;形成一个无中心的网状结构。Mesh网络常见于分布式计算、传感器网络、互联网等场景中。另外&#xff0c;在3D计算机图形学中&#xff0c;M…

MATLAB 之 Simulink 系统仿真实例和 S 函数的设计与应用

这里写目录标题 一、Simulink 系统仿真实例1. 方法一2. 方法二3. 方法三 二、S 函数的设计与应用1. 用 MATLAB 语言编写 S 函数1.1 主程序1.2 子程序 2. S 函数的应用 一、Simulink 系统仿真实例 下面的应用实例我们将分别采用不同建模方法为系统建模并仿真。例如&#xff0c;…

【AUTOSAR】BMS开发实际项目讲解(三十一)----电池管理系统电池热管理功能

电池热管理功能 关联的系统需求 Sys_Req_4101、Sys_Req_4102、Sys_Req_4103、Sys_Req_4104、Sys_Req_4105; 功能实现描述 为保证电池系统的热安全&#xff0c;以及电池系统不同温度环境下的工作性能&#xff0c;本车型具备热管理功能。 表-热管理功能配置 功能 功能描述 …

vim多文件切换快捷键设置

1、基本切换指令 vim中在打开多个文件时&#xff0c;会有多个文件进行切换的需求。按:bn切换到下一个文件&#xff0c;按:bp切换到上一个文件。 2、快捷键设置 为了便捷操作&#xff0c;将切换命令设置成快捷键。 进入/home/yys个人目录下&#xff0c;vim .vimrc进入vimrc文…

java新特性stream

stream Java 8 是一个非常成功的版本&#xff0c;这个版本新增的Stream&#xff0c;配合同版本出现的 Lambda &#xff0c;给我们操作集合&#xff08;Collection&#xff09;提供了极大的便利。 Stream将要处理的元素集合看作一种流&#xff0c;在流的过程中&#xff0c;借助…