【C++初阶】C++入门——缺省参数、函数重载

news2024/11/16 16:46:17

在这里插入图片描述

目录

  • 一、缺省参数
    • 1.1 定义
    • 1.2 缺省参数分类
    • 1.3 缺省参数只能出现在函数声明中
  • 二、函数重载
    • 2.1 定义
    • 2.2 构成重载的几种情况
    • 2.3 C++支持函数重载的原理

一、缺省参数

1.1 定义

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

//缺省参数
void fun(int a = 10)
{
	cout << a << endl;
}

int main()
{
	fun(2);//传参了,使用显式传递的值
	fun();//没有传参,使用缺省参数
}

在这里插入图片描述
 上面代码在fun函数的形参部分给了缺省值10,这意味着在调用fun函数的时候可以传参,也可以不传参,如果传参了那形参a就使用显式传的值,如果没有传参那形参a就使用缺省值10。

1.2 缺省参数分类

  • 全缺省参数
void text(int a = 5, int b = 15, int c = 25)//全缺省,所有参数都给了缺省值
{
	cout << a << ' ';
	cout << b << ' ';
	cout << c << ' ';
	cout << endl;
}

int main()
{
	text(1, 2, 3);
	text(1, 2);
	text(1);
	text();
	return 0;
}

在这里插入图片描述
 对于全缺省参数在传参的时候,参数是按照从左往右的顺序进行缺省的,不能跳着缺省,即:让第一个形参和第三个形参都使用显式传递值,而让第二个参数使用缺省值,这种做法是不被允许的。以上的代码为例:当一个参数也没传的时候,形参全部使用缺省值;只传一个参数的时候,这个参数会赋值给第一个形参,后面两个形参使用缺省值;传两个参数的时候,会把第一个实参赋值给第一个形参,把第二个实参赋值给第二个形参,最后一个形参使用缺省值;传三个参数的时候,所有形参都是用实参传过来的值。这里要与参数压栈区分,参数压入栈桢的顺序是从右往左。

  • 半缺省参数
void text(int a, int b = 15, int c = 25)//半缺省,只有部分参数给了缺省值
{
	cout << a << ' ';
	cout << b << ' ';
	cout << c << ' ';
	cout << endl;
}

int main()
{
	text(1, 2, 3);
	text(1, 2);
	text(1);
	return 0;
}

注意:
 半缺省参数必须从右往左依次给缺省值,即:第一个形参和第二个形参给了缺省值,而第三个形参没有给缺省值,这种情况是不被允许的。也不能隔着给,即:第三个形参和第一个形参给了缺省值,而第二个形参没有给缺省值,这种情况也是不被允许的。

1.3 缺省参数只能出现在函数声明中

 为了避免出现不一致的情况,要求缺省参数不能在函数声明和定义中同时出现,并且只能出现在函数的声明中。为什么不能只出现在函数的定义中?
 因为在预处理阶段会把头文件展开,一般函数的声明就放在头文件中。如果只在函数的定义中给了缺省值,那头文件展开后,函数的声明语句中并没有缺省参数,此时如果在调用该函数的时候没有传参希望使用它的缺省值,那在程序编译的过程中就会出现问题,即:函数的声明没给出缺省值,意味着需要显式传参,但在调用该函数的时候却没有传参。

二、函数重载

 在自然语言中,一个词可以有多重含义,人们可以通过上下文来判断该词真实的含义,即该词被重载了。比如:有人说,我们国家有两个体育项目大家根本不用看,也不用担心。一个是乒乓球,一个是男足。前者是“谁也赢不了!”,后者是“谁也赢不了!”但是大家懂的都懂,前者意思是谁都赢不了我们,而后者的意思是我们赢不了别人。

2.1 定义

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

2.2 构成重载的几种情况

  • 参数类型不同:
int Add(int left, int right)
{
	cout << "int Add(int left, int right)" << endl;
	return left + right;
}
double Add(double left, double right)
{
	cout << "double Add(double left, double right)" << endl;
	return left + right;
}
int main()
{
	cout << Add(1, 2) << endl;
	cout << Add(1.0, 2.0) << endl;
}

在这里插入图片描述
 上面的代码定义了两个同名的Add函数,但是它们的参数类型不同,第一个两个参数都是int型,第二个两个参数都是double型,在调用Add函数的时候,编译器会根据所传实参的类型自动判断调用哪个函数。至于编译器为什么能这么做稍后再说。

  • 参数个数不同:
void fun()
{
	cout << "f()" << endl;
}
void fun(int a)
{
 cout << "f(int a)" << endl;
}
int main()
{
	fun();
	fun(1);
	return 0;
}

在这里插入图片描述

  • 参数类型顺序不同:
// 3、参数类型顺序不同
void Text(int a, char b)
{
	cout << "Text(int a,char b)" << endl;
}
void Text(char b, int a)
{
	cout << "Text(char b, int a)" << endl;
}

int main()
{
	Text(1, 'a');
	Text('a', 1);
	return 0;
}
  • 有缺省参数的情况
void fun()
{
	cout << "f()" << endl;
}
void fun(int a = 10)
{
 cout << "f(int a)" << endl;
}
int main()
{
	//fun();//无参调用会出现歧义
	fun(1);//调用的是第二个
	return 0;
}

 上面代码中的两个fun函数根据函数重载的定义他俩是构成函数重载的,编译可以通过,因为第一个没有参数,第二个有一个整型参数,属于上面的参数个数不同的情况。但是fun函数存在一个问题:在无参调用的时候会产生歧义,因为对两个fun函数来说,都可以不传参。
注意:
 返回值的类型与函数是否构成重载无关。即:函数名相同,形参列表形相同,返回值不同不会构成函数重载。
在这里插入图片描述

2.3 C++支持函数重载的原理

 上面说到,编译器会自动根据参数的类型去判断应该调用哪个函数,那编译器究竟是如何做到的呢?要回答这个问题会涉及到一些编译链接的知识,遗忘的同学可以去看看我之前的文章:【C语言进阶】编译链接。
 其实这里涉及到函数签名的概念,函数签名包含了一个函数的信息,包括函数名、它的参数类型、他所在的类和名称空间以及其他信息。函数签名用于识别不同的函数,就像签名用于识别不同的人一样,函数的名字只是函数签名的一部分。对于函数名相同,参数列表不同的函数,编译器和链接器处理符号的时候,它们使用某种名称修饰的方法(不同的编译器会有所不同),使得每个函数签名对应一个修饰后名称。编译器在汇编过程中,会将函数和变量的名字进行修饰,形成符号名,也就是说C++的源代码编译后的目标文件中所使用的符号名是相应的函数和变量的修饰后名称。C++编译器和链接器都使用符号来标识和处理函数和变量,所以对于不同函数签名的函数,即使函数名相同,编译器和链接器都认为他们是不同的函数。
 由于Windows下的修饰规则过于复杂,而Linux下g++的修饰规则简单易懂,所以下面我将利用g++演示经过修饰后的名称。以下面这段代码为例:

#include <stdio.h>                                                                                                                                                                                            
int Add(int left, int right)
{
	printf("int Add(int left, int right)\n");
	return left + right;
}

double Add(double left, double right)
{
	printf("double Add(double left, double right)\n");
	return left + right;
}
int main()
{
	Add(1,2);
	Add(1.0,2.0);
	return 0;
}

 先用g++ text.cpp -o text.out这条指令对上面的代码进行编译生成一个可执行程序tetx.out,再用objdump -S text.out指令查看修饰后名称。
在这里插入图片描述
 其中_Z是固定的前缀;3表示函数名的长度;Add就是函数名;i是int的缩写,两个i表示两个参数都是int类型,d是double的缩写,两个d表示两个参数都是double类型。C++就是通过函数修饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载。通过分析可以发现,修饰后的名称中并不包含任何于函数返回值有关的信息,因此也验证了上面说的返回值的类型与函数是否构成重载无关。
 再来看看C语言编译器gcc的处理结果
在这里插入图片描述
 可以看出经过gcc编译后,函数名字的修饰没有发生改变。这也就是为什么C语言不支持函数重载,因为同名函数没办法区分。


 今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下,您的支持就是春人前进的动力!
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

下一代Windows被披露,任何硬件都能运行

这么些年来&#xff0c;微软似乎一直没能打破 Windows 系统隔代香魔咒。 继 Win XP 惊艳世界后 Win Vista 表现平平&#xff0c;到 Win 7 引领一个时代&#xff1b; 接着 Win 8 含泪淹没在前代耀眼光环之下&#xff0c;直到 Win 10 再创辉煌成功走入家家户户。 而最新的 Win …

vue-antd-admin——关闭当前页面,跳转到指定页面——bus事件总线的用法

最近在写后台管理系统时&#xff0c;遇到一个需求&#xff1a; 关闭当前页面&#xff0c;然后跳转到指定页面。 具体实现方法如下&#xff1a; 1.tabsView.vue文件中添加bus文件&#xff0c;并实现跨组件之间的监听 1.1 引入bus文件 import Bus from /utils/bus; bus文件内…

C#winform自定义圆角按钮控件

本篇介绍自定义圆角渐变按钮,实现过程,实现效果如下 创建winform项目,添加组件类控件 修改的名称为ButtonEx,并点击添加 修改cs中的代码 using System; using System.ComponentModel;using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms;…

HKDF秘钥生成算法

HKDF叫HMAC-based KDF(key derivation function)&#xff0c;基于HMAC的密钥推导函数&#xff0c;所以我们先认识HMAC算法。 1. HMAC 基于一个共同密钥&#xff0c;在两个对端之间提供消息完整性确认的机制叫"message authentication codes(MAC)&#xff0c;消息认证码&…

【CSS】CSS使用变量与变量定义

如何定义可以在CSS中使用的变量 CSS变量&#xff08;也称为自定义属性&#xff09;的定义规则如下&#xff1a; 使用–作为前缀&#xff0c;后跟变量名。变量名可以由字母、数字、连字符和下划线组成&#xff0c;并且不能以连字符开头。变量名区分大小写。变量定义在选择器范…

数据中心可视化——智慧机房数字孪生,高效运维管理

IDC&#xff08;Internet Data Center&#xff09;数据中心可视化是指通过可视化的方式对数据中心的运行状态、资源使用情况、安全监控等进行展示和管理。可以帮助管理员更好地了解数据中心的运行情况和趋势&#xff0c;及时发现问题并采取措施&#xff0c;提高数据中心的运行效…

鼠标悬停,用气泡形式提示用户信息

需求 鼠标悬停,用气泡形式提示用户名字信息 效果图 分析 图中深浅两色的小方块是由v-if遍历二维数组得来的,所以这个需求本质上是原生html元素的出现与隐藏,重点在于知道显示或隐藏哪一个元素 代码 <!-- shelvesList就是后台给前端的,关于库位信息的二维数组 --> &l…

用RunnerGo平替JMeter?这个测试平台确实可以!

1、前言 目前在性能测试领域市场jmeter占有率非常高&#xff0c;主要原因是相对比其他性能测试工具使用更简单&#xff08;开源、易扩展&#xff09;&#xff0c;功能更强大&#xff08;满足多种协议的接口&#xff09;&#xff0c;但是随着研发协同的升级&#xff0c;平台化…

java版本企业电子招标采购系统源码+二次开+Spring Cloud + Spring Boot 发

一、立项管理 1、招标立项申请 功能点&#xff1a;招标类项目立项申请入口&#xff0c;用户可以保存为草稿&#xff0c;提交。 2、非招标立项申请 功能点&#xff1a;非招标立项申请入口、用户可以保存为草稿、提交。 3、采购立项列表 功能点&#xff1a;对草稿进行编辑&#x…

耳骨传导耳机哪个牌子好,几款实战性高的耳骨传导耳机分享

骨传导耳机是一种利用骨头直接传声的耳机&#xff0c;因为它不需要通过耳道来听音乐&#xff0c;所以能够更好地保护听力&#xff0c;也不会因为佩戴耳机而影响到我们正常的交流&#xff0c;可以说是一种比较健康的耳机。不过骨传导耳机的价格相对于普通蓝牙耳机来说还是要贵一…

二叉树题目:相同的树

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;相同的树 出处&#xff1a;100. 相同的树 难度 3 级 题目描述 要求 给你两个二叉树的根结点 p \texttt{p} p …

振动在线监测:如何优化您的设备维护计划?

在工业生产中&#xff0c;设备的维护计划对于确保设备可靠性和生产效率至关重要。而振动在线监测作为一种先进的技术手段&#xff0c;可以实时监测设备振动情况&#xff0c;帮助企业优化维护计划&#xff0c;提高设备维护效率。本文将介绍振动在线监测的重要性&#xff0c;并分…

SparkSQL的分布式执行引擎(Spark ThriftServer)

文章目录 1.Spark ThriftServer2.启动 Spark ThriftServer3.Beeline方式连接4.DataGrip方式连接5. 代码方式6. SparkSQL运行方式7.参考文章 1.Spark ThriftServer Spark ThriftServer 相当于一个持续性的Spark on Hive集成模式&#xff0c;可以启动并监听在10000端口&#xff…

182_Power BI 使用 DAX 按照先进先出原则计算毛利润

182_Power BI 使用 DAX 按照先进先出原则计算毛利润 一、背景 在笔者以往的文章中也有先进先出的案例&#xff0c;可以参考(https://jiaopengzi.com/?s%E5%85%88%E8%BF%9B%E5%85%88%E5%87%BA)。 今天我们来看一个网友提出的问题&#xff0c; 先进先出的原则&#xff0c;入…

ATM模拟机-实战开发-前期准备

需求分析 项目名称&#xff1a;ATM模拟存取钱系统 目录 需求分析 项目名称&#xff1a;ATM模拟存取钱系统 项目目标功能分析&#xff1a; 用户功能&#xff1a; 提供功能 基本功能 管理员功能&#xff1a; 提供功能 基本功能 详细分析 用户功能 管理员功能 用户…

ModaHub大禹智库:ModelScope魔搭社区的“下载数据严重造假“的说法可能存在一定的合理性

目录 首先&#xff0c;我们需要了解ModelScope魔搭社区的运营模式和数据收集方式。 其次&#xff0c;我们需要考虑ModelScope魔搭社区的用户群体和应用场景。 此外&#xff0c;我们还需要考虑ModelScope魔搭社区的发展时间和市场竞争情况。 综上所述&#xff0c;ModelScope…

PHP反序列化漏洞之Phar

目录 1、认识phar类型文件 2、制作phar文件 3、phar的上传与读取 4、漏洞利用的条件 1、认识phar类型文件 这种文件可以通过phar协议来读取&#xff08;使用phar://后面接文件路径即可读取&#xff09; 先给大家看一下phar文件的大致样子&#xff1a; 它一般包括头部信息&…

Windows10下使用wsl2+ubuntu1804

一定好好看官方文档 适用于 Linux 的 Windows 子系统文档 | Microsoft Learn 一、安装WSL 1.1、方式一&#xff1a; 现在&#xff0c;可以使用单个命令安装运行 WSL 所需的一切内容。 在管理员模式下打开 PowerShell 或 Windows 命令提示符&#xff0c;方法是右键单击并选择…

OpenAI Gym入门与实操(3)

接前一篇文章&#xff1a;OpenAI Gym入门与实操&#xff08;2&#xff09; 本文内容参考&#xff1a; Getting Started With OpenAI Gym | Paperspace Blog&#xff0c; 【强化学习】 OpenAI Gym入门&#xff1a;基础组件&#xff08;Getting Started With OpenAI Gym: The B…

leetcode 989.数组形式的整数加法

⭐️ 题目描述 &#x1f31f; leetcode链接&#xff1a; 数组形式的整数加法 ⭕️ 代码&#xff1a; /*思路&#xff1a;数组从后往前和k的低位相加&#xff0c;若大于等于10则进一.[1 , 2 , 0 , 0] 3 44 3 2 1 最后逆置数组即可。 */ int* addToArrayForm(…