C++ | 详细介绍缺省参数的作用

news2025/1/24 7:17:22

在这里插入图片描述

在这里插入图片描述

文章目录

  • 一、前言
    • 1、缺省参数概念
    • 2、缺省参数的使用规则
  • 二、全缺省参数【备胎是如何使用的♿】
    • 1、四种实参传递方式说明
    • 2、疑难细究
  • 三、半缺省参数【⭐】
    • 1、错误用法示范
    • 2、正确用法示范
    • 🔥实参缺省与形参缺省的混合辨析🔥
    • 3、小结
  • 四、缺省参数的实际应用 —— 栈
  • 五、总结与提炼

一、前言

1、缺省参数概念

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

  • 通俗点讲,就是在定义函数的时候可以给形参赋一个初始化的值,这个值就叫做缺省值,缺省值可以有一个,也可以有多个

2、缺省参数的使用规则

  1. 半缺省参数必须从右往左依次且连续来给出,不能间隔着给【实参和形参同理】
  • 可以通过下图先了解一下,下文我会详细介绍。可以看出对于形参中的缺省参数如果要给的话不可以随意给,要么从右往左给1个或者是2个,要么全部缺省,否则必须要连续。否则就不符合规定

在这里插入图片描述
2. 缺省参数不能在函数声明和定义中同时出现

  • 可以看到,若是在声明和定义中同时给出函数的缺省参数,此时就会出现【重定义默认参数】的问题。下面我所给出的值是相同的,若是两边给出的值不同的话,编译器在编译的时候就会产生歧义,不知道使用那一块的参数

在这里插入图片描述

  • 一般我们会选择定义在声明处,因为声明处的头文件其他.cpp文件可以包含。若是将这些缺省参数放在放在了定义出,其他文件就没办法使用到了

在这里插入图片描述
3. 缺省值必须是常量或者全局变量

  • 这一点很好理解,你给出的缺省值必须是一个固定的值,而不是一个可修改的变量,否则这个缺省值将毫无意义;对于缺省值一般我们不会使用全局变量,因为全局变量会存在线程安全的问题,日常写代码也是不推荐使用全局变量
  1. C语言不支持(编译器不支持)
  • 演示一下,创建了一个test.c的源文件的,然后和上面一样为这里的函数形参给到缺省值,接着去编译的话就可以发现是会出现很多错误的,这其实就可以看出C语言是不支持【缺省参数】的

在这里插入图片描述


因为对于缺省参数而言,虽然看上去很好理解,不过你真正去使用的话若是不注意会出现很多错误,了解了基本的概念和使用规则之后,接下去就让我们真正地去研究一下这个缺省参数

二、全缺省参数【备胎是如何使用的♿】

1、四种实参传递方式说明

  • 首先来看一下全缺省参数,对于全缺省参数而言全部的形参值都给上一个缺省值,也就像下面这样
void func(int a = 10, int b = 20, int c = 30)
{
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl;
}
  • 然后我们便可以试着是去调用一下这个函数,因为有缺省参数的存在,可以不考虑传入全部的值,首先对于下面这种就是最常见的,那也就是传入所有的参数。【假设默认缺省值均为备胎,a为备胎1号,b为备胎2号,c为备胎3号】那么此时这样的传值是不需要备胎的
func(1, 2, 3);
  • 然后试着传入前两个实参试试,那此时最后一个使用的就是默认的缺省参数30,也就是备胎3号【今天晚上想看场电影,但是电影票有点贵,所以叫来备胎3号
func(1, 2);
  • 接下去试着只传入一个参数,那后面两个b和c使用的就是默认的缺省参数20和30【早饭自己家里吃,中午吃饭叫来备胎2号付钱,晚上和备胎3号吃完饭然后看电影
func(1);
  • 下面这种应该不用我说了,典型的绿茶🍵使用的都是三个缺省值10、20、30【早上让备胎一号早起帮忙买早饭,中午和备胎2号去高档餐厅吃饭,晚上和备胎3号去湖边约会
func();

来看一下运行结果。和我上面解释是一样的

在这里插入图片描述

2、疑难细究

  • 可以看出,刚才我都是执行【从右往左依次连续给出缺省值】的,但若是我像下面这样传递参数的话,虽然是规则对的,但语法是错误的
func(, 1);
func(, 1, 2);
func(, ,1);

在这里插入图片描述

三、半缺省参数【⭐】

如果说全缺省参数比较好理解一些,那半缺省参数就够我们喝一壶了

【概念】:并不是所有的形参都有缺省值,可以缺省一个,也可以缺省多个

void Func(int a = 10, int b = 20, int c = 30)

例如像上面这种就是典型的半缺省参数

1、错误用法示范

① 没有从右往左进行缺省

  • 对于下面三种而言,就是非常明显得没有从右往左去给出缺省值,只是给出了前两个缺省值或者是给出了第一个或者第二个缺省值
  • 若是想要给出第2个缺省值,那么第3个就必须给出;若是想要给出第1个缺省值,那么那么第2个和第3个就必须给出
void func(int a = 10, int b = 20, int c)
void func(int a = 10, int b, int c)
void func(int a, int b = 20, int c)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

② 没有连续地给出缺省值

  • 对于第二种而言就是的虽然最后一个缺省值给出了,并且第一个缺省值也给出了,但是呢第二个缺省值却没有给出,这其实出现问题了,因为存在不连续的缺省值
  • 上面说到过,若是想要给出第1个缺省值,那么那么第2个和第3个都必须给出
void func(int a = 10, int b, int c = 30)

在这里插入图片描述

2、正确用法示范

知道了怎样给缺省值是错误的之后我们来看看正确的半缺省参数应该如何给出

  • 通过对比可以发现下面的这些全部满足【从右往左依次连续给出缺省值】,满足了若是前一个有缺省值后一个也连续的也必须有缺省值的条件
void func(int a, int b = 20, int c = 30)		//✔	后两个缺省
void func(int a, int b, int c = 30)				//✔	最后一个缺省
  • 对于下面的这两种就比较特殊,第一个就是全部没有缺省值,那其实就是我们平时正常写函数的样子;而对于第二个就是全部给出缺省值,那其实也就是上面说到过的全缺省参数,对于它的调用方式比较多,我在上面已经演示过了
void func(int a, int b, int c)					//✔	全部不缺省(正常形参)
void func(int a = 10, int b = 20, int c = 30)	//✔	全部缺省【调用方式多】

🔥实参缺省与形参缺省的混合辨析🔥

通过了学习了半缺省参数,接下去我将带你通过实参传值,形参接收的形式,再度来辨析一下【半缺省参数】的难点究竟在哪里

  1. 第一形参无缺省,至少传入一个实参
void func(int a, int b = 20, int c = 30)
func(1, 2, 3);		//a = 1  b = 2  c = 3
func(1, 2);			//a = 1  b = 2  c = 30
func(1);			//a = 1  b = 20 c = 30
func();				//a = ?  b = 20 c = 30
  • 可以看到,因为第一个形参没有给出缺省参数值,所以在传参的时候必须给到形参a一个值,可以看出编译器检查得严格,若是检查得不严格那么打印出来的就是一个随机值

在这里插入图片描述


  1. 第一、二形参无缺省,至少传入两个实参
void func(int a, int b, int c = 30)
func(1, 2, 3);		//a = 1  b = 2  c = 3
func(1, 2);			//a = 1  b = 2  c = 30
func(1);			//a = 1  b = ?  c = 30
func();				//a = ?  b = ?  c = 30
  • 此时,当前两个形参都没有缺省参数值时,那么在传参的时候就必须给形参a和形参b都传入一个值,那就是必须要传入两个值,可以不传入第3个实参,因为第三个形参有默认缺省值

在这里插入图片描述


  1. 三个形参均为缺省参数,需传入三个实参
void func(int a, int b, int c)
func(1, 2, 3);		//a = 1  b = 2  c = 3
func(1, 2);			//a = 1  b = 2  c = ?
func(1);			//a = 1  b = ?  c = ?
func();				//a = ?  b = ?  c = ?
  • 最后这一种,就是当所有的形参缺省值都没有给出的时候,此时就是我们在C语言中写的正常函数形式,三个形参就必须传入三个实参,缺一不可

在这里插入图片描述

3、小结

  • 形参缺省不是缺了一个值,而是给了一个默认参数值。
  • 不仅是在给出半缺省形参值时需要注意【从右往左依次连续给出】;在给具有半缺省参数的函数传递实参的时候,要注意传入实参的个数必须符合给出的缺省形参个数

四、缺省参数的实际应用 —— 栈

如果你认真自己地看下来,就会觉得大吃一惊,原来缺省参数还有这么多细节是被忽略的,那了解到这些之后可以带来什么实际的意义呢?

  • 可以看到,这是我们在数据结构 — 栈中写的代码,定义了一个栈的结构体和一个对其进行初始化的Init函数。在初始化时我将这个栈的大小设置为4,以及这个容量大小Capacity也为4
struct Stack {
	int* a;
	int top;
	int Capacity;
};

void InitStack(struct Stack* st)
{
	st->a = (int*)malloc(sizeof(int) * 4);
	st->top = 0;
	st->Capacity = 4;
}
  • 此时我在外界普通得定义了一个栈,然后对其去进行一个初始化,后续的话再对其进行一些入栈和出栈的操作,对于顺序栈来说可能会出现栈满容量不够的情况,所以在Push的时候会有一个扩容的逻辑
  • 但是一直这么容量不够去扩容的话也是会存在消耗的,因为我一开始给的只有4个空间的大小。但若是一开始就给到很大的容量比如说100,但是数据量只在10以内,这又会存在一个浪费的现象
struct Stack st;
InitStack(&st);

上面这种其实就是因为一开始初始化给到的栈容量太大或者太小导致的,若是我们在提前知道当前数据量的情况下可以手动给出栈的容量时,就不会导致这种情况了,此时就可以使用到我们本文所学习的【缺省参数】了

  • 此时我们可以对栈的初始化函数做一个改进,添加一个defaultCapacity默认容量这个参数,然后为其设置一个缺省参数为4
  • 从缺省参数的规则可以看出,【从右往左依次连续给出】没有问题,对于实参传递不会有问题,肯定不会忘了传入栈的地址,那么这个默认容量就可传可不传了
void InitStack(struct Stack* st, int defaultCapacity = 4)
{
	st->a = (int*)malloc(sizeof(int) * defaultCapacity);
	st->top = 0;
	st->Capacity = defaultCapacity;
}
  • 此处我定义了两个栈,因为知晓了第一个栈的数据量是80个,所以可以去手动初始化一个默认容量为100大小的栈;可以对于第二个栈,我不知道数据量的大小,此时我可以选择不传入实参,函数内部就会默认使用给出的缺省参数值4,那么这个栈的初始大小就为4
struct Stack st;
InitStack(&st, 100);

struct Stack st2;
InitStack(&st2);

这就是有关缺省参数实际应用的案例,当然不止这一个,我只是举个例子,在C++中有很多地方都会使用到这个【缺省参数】,比方说还有六大成员函数之一的构造函数若是你对其语法非常熟悉的话,用起来就会非常得顺手

五、总结与提炼

最后我们来总结一下本文所学习的内容

  • 在一开始,首先认识了什么叫做【缺省参数】,知道了其使用的一些规则
  • 接下去,我们学习了两种缺省参数的形式,一个是全缺省参数,一个则是半缺省参数。对于前者,我演示了四种实参传递的方式,向你展现了备胎是如何被使用的;对于后者,虽然看上去很简单,但若是细细地去研究其语法的话就会发现,还是存在许许多多的小细节需要注意的,最主要的就是要记住一点,对于缺省参数值一定要【从右往左依次连续给出
  • 最后,我们在学习了缺省参数后知道了如何去将其运用在实际的开发中,这一点需要在学习C++的过程中细细体会

以上就是本文要介绍的所有内容,感谢您的阅读🌹

在这里插入图片描述

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

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

相关文章

XILINX AXI总线学习

AXI介绍什么是AXI&#xff1f;AXI&#xff08;高级可扩展接口&#xff09;&#xff0c;是ARM AMBA的一部分&#xff1b;AMBA:高级微控制器总线架构&#xff1b;是1996年首次引入的一组微控制器总线&#xff1b;开放的片内互联的总线标准&#xff0c;能在多主机设计中实现多个控…

电子台账:模板制作之五——二级过滤与多条件组合

1 前言工作中&#xff0c;经常会遇到很复杂的数据&#xff0c;比如内销产品和出口产品、正常产品和报废产品都混在一块儿。电子台账中&#xff0c;需要把这些数据都区分开&#xff0c;分别汇总。这种情况&#xff0c;可以用台账软件的二级过滤功能来处理&#xff0c;实际上就是…

QML Popup详解

1.简介 弹出式用户界面控件&#xff0c;它可以与Window或ApplicationWindow一起使用&#xff0c;默认不可见。 常用属性介绍&#xff0c;一些公用的基础属性就不作介绍&#xff0c;可以查看我前面写的文章。 closePolicy : enumeration &#xff1a;此属性决定弹出窗口关闭的…

【Java基础】HashMap的底层数据结构是怎样的?

HashMap就是以Key-Value的方式进行数据存储的一种数据结构。 HashMap在jdk1.7之前和jdk1.8之后的底层数据结构是不一样的。 在jdk1.7之前是数组链表的形式&#xff0c;并通过entry节点保存key和value值&#xff1b;当Hash冲突比较严重的时候&#xff0c;在数组上形成的链表就会…

【ArcGIS学习记录02】--利用DEM数据提取河网溪流

【ArcGIS学习记录02】–利用DEM数据提取河网溪流 注&#xff1a;本文仅作为自己的学习记录以备以后复习查阅 不得不说这读个研究生可太不容易了&#xff0c;啥都得会点&#xff0c;这也得学那也得学&#xff0c;我的脑容量快要不够了。。。。。 一 数据准备&#xff08;DEM数…

[数据结构]:14-选择排序(顺序表指针实现形式)(C语言实现)

目录 前言 已完成内容 选择排序实现 01-开发环境 02-文件布局 03-代码 01-主函数 02-头文件 03-PSeqListFunction.cpp 04-SortCommon.cpp 05-SortFunction.cpp 结语 前言 此专栏包含408考研数据结构全部内容&#xff0c;除其中使用到C引用外&#xff0c;全为C语言代…

使用Ubuntu中的Docker部署Remix

一、简介1.博主这里使用的是腾讯云的服务&#xff0c;然后使用Docker进行部署Remix。2.踩了几个坑&#xff0c;没有花费过多时间&#xff0c;所以这篇文章会记录踩过的坑。然后避免你们掉进去&#xff0c;然后花费过多时间。3.这里就不写怎么安装Docker了&#xff0c;因为博主上…

UML学习备忘录

UML学习备忘录 UML 全称是 Unified Modeling Language&#xff08;统一建模语言&#xff09;&#xff0c;它以图形的方式来描述软件的概念。它的特点是简单、统一、图形化、能表达软件设计中的动态与静态信息。UML的本质就是为了交流。 UML的概念包括了UML语义&#xff08;Se…

前端ES5对象特性

ES5对象特性 对象和函数的原型 JS中每一个对象都有一个特殊的内置属性&#xff0c;这个特殊的对象可以指向其他的对象 我们通过引用对象的属性key来获取一个value时&#xff0c;它会触发 Get 的操作首先检查该对象是否有对应的属性&#xff0c;如果有的话就使用对象内的如果…

Pytorch中utils.data 与torchvision简介

Pytorch中utils.data 与torchvision简介1 数据处理工具概述2 utils.data简介3 torchvision简介3.1 transforms3.2 ImageFolder1 数据处理工具概述 Pytorch涉及数据处理&#xff08;数据装载、数据预处理、数据增强等&#xff09;主要工具包及相互关系如下图所示&#xff0c;主…

文献阅读(48)—— 长序列time-series预测【Informer】

文献阅读&#xff08;48&#xff09;—— 长序列time-series预测【Informer】 文章目录文献阅读&#xff08;48&#xff09;—— 长序列time-series预测【Informer】先验知识/知识拓展文章结构文章方法1. 文章核心网络结构&#xff08;1&#xff09; 传统意义上的transformer应…

数据结构4——线性表3:线性表的链式结构

基本概念 ​ 链式存储结构用一组物理位置任意的存储单元来存放线性表的数据元素。 ​ 这组存储单元既可以是连续的又可以是不连续的甚至是零散分布在任意位置上的。所以链表中元素的逻辑次序和物理次序不一定相同。而正是因为这一点&#xff0c;所以我们要利用别的方法将这些…

Kafka消息中间件(Kafka与MQTT区别)

文章目录KafkaKafka重要原理Topic 主题Partition 分区Producer 生产者Consumer 消费者Broker 中间件Offset 偏移量Kafka与mqtt区别Kafka Kafka是一个分布式流处理平台&#xff0c;它可以快速地处理大量的数据流。Kafka的核心原理是基于发布/订阅模式的消息队列。Kafka允许多个…

C++基础——C++面向对象之重载与多态基础总结(函数重载、运算符重载、多态的使用)

【系列专栏】&#xff1a;博主结合工作实践输出的&#xff0c;解决实际问题的专栏&#xff0c;朋友们看过来&#xff01; 《QT开发实战》 《嵌入式通用开发实战》 《从0到1学习嵌入式Linux开发》 《Android开发实战》 《实用硬件方案设计》 长期持续带来更多案例与技术文章分享…

MySQL8.0.16存储过程比5.7.22性能大幅下降

MySQL8.0.16存储过程比5.7.22性能大幅下降 1、背景 从5.7.22迁移数据库到8.0.16&#xff0c;发现存储过程执行性能大幅下降。原来在5版本上执行只需要3-5秒&#xff0c;到8版本上居然要达到上万秒。 5版本&#xff1a; call Calculation_Week() OK 时间: 3.122s 8版本&#x…

移动通信(16)信号检测

常见的信号检测算法一般包括以下几类检测算法&#xff1a;最优、线性和非线性。最优检测算法&#xff1a;最大似然算法线性检测算法&#xff1a;迫零检测算法和最小均方误差检测算法非线性检测算法&#xff1a;串行干扰消除检测算法球形译码检测算法属于一种次优检测算法&#…

凤凰游攻略

凤凰游攻略1 装备&#x1f4e6;1.1 证件1.2 日常用品1.3 药品1.4 衣物1.5 洗漱用品2 交通&#x1f697;3 住宿&#x1f3e0;4 美食&#x1f355;5 拍照&#x1f4f7;5.1 租苗族服5.1.1 单租服装5.1.2 服装化妆5.2 一条龙旅拍6 路线&#x1f5fa;️景点&#x1f3d9;️7 注意⚠️…

计算机网络的166个概念你知道几个 第十二部分

计算机网络安全安全通信的四大要素&#xff1a;机密性、保温完整性、端点鉴别和运行安全性。机密性&#xff1a;报文需要在一定程度上进行加密&#xff0c;用来防止窃听者截取报文。报文完整性&#xff1a;在报文传输过程中&#xff0c;需要确保报文的内容不会发生改变。端点鉴…

java StringBuilder 和 StringBuffer 万字详解(深度讲解)

StringBuffer类介绍和溯源StringBuffer类常用构造器和常用方法StringBuffer类 VS String类&#xff08;重要&#xff09;二者的本质区别&#xff08;含内存图解&#xff09;二者的相互转化StringBuilder类介绍和溯源StringBuilder类常用构造器和常用方法String类&#xff0c;St…

0308java基础-注解,反射

一&#xff0c;注解 1.什么是注解&#xff1a; Annotation是从jdk5.0开始引入的新技术作用&#xff1a; 不是程序本身&#xff0c;可以对程序作出解释可以被其他程序读取格式&#xff1a; 以注释名在代码中存在&#xff0c;还可以添加一些参数值SuppressWarnings(value"…