【C++掌中宝】缺省参数的全面解析

news2024/9/23 14:41:37

在这里插入图片描述

文章目录

  • 前言
  • 1. 什么是缺省参数?
  • 2. 缺省参数的分类
    • 2.1 全缺省【备胎是如何使用的😅】
      • 2.1.1 疑难细究
    • 2.2 半缺省
      • 2.2.1 错误用法示范
      • 2.2.2 正确用法示范
      • 2.2.3🔥实参缺省与形参缺省的混合辨析🔥
  • 3. 缺省参数的规则和限制
  • 4. 规定必须函数声明给缺省值
  • 5. 缺省参数 vs 重载函数
  • 6. 其它常见问题和注意事项
    • 6.1 缺省参数的表达式计算时机
    • 6.2 静态和可变参数问题
  • 结语

前言

C++中的缺省参数使得函数调用更加灵活,减少了重复代码,提高了代码的可读性。然而,使用时必须遵守一些规则,如顺序要求和声明与定义中只能出现一次。理解这些规则和限制可以帮助开发者更好地利用C++的强大特性,编写出更加简洁和高效的代码。

1. 什么是缺省参数?

在函数设计中,缺省参数(也称为默认参数)是指函数参数可以在调用时被省略,省略的参数会自动使用预定义的默认值。这使得函数的调用更加灵活,无需为每个参数显式传递值。

在C++中,缺省参数允许程序员在声明或定义函数时为参数提供默认值。例如,以下是一个简单的函数声明:

int my_func(int a, int b, int c = 12);

在这个例子中,c有一个缺省值12。这意味着当调用my_func(1, 2)时,c的值自动为12。如果调用my_func(1, 2, 3),则c的值会被显式传递的值3覆盖。

2. 缺省参数的分类

缺省参数分为全缺省和半缺省参数。

  • 全缺省指所有的函数参数都有默认值,这使得调用函数时可以选择传递所有参数、部分参数,甚至不传参数。

  • 半缺省是指部分参数有默认值,通常从右向左依次进行缺省。

2.1 全缺省【备胎是如何使用的😅】

  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);
  1. 然后试着传入前两个实参试试,那此时最后一个使用的就是默认的缺省参数30,也就是备胎3号【今天晚上想看场电影,但是电影票有点贵,所以叫来备胎3号
func(1, 2);
  1. 下面这种应该不用我说了,典型的绿茶🍵使用的都是三个缺省值10、20、30【早上让备胎一号早起帮忙买早饭,中午和备胎2号去高档餐厅吃饭,晚上和备胎3号去湖边约会
func();

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

在这里插入图片描述

2.1.1 疑难细究

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

func(, 1);
func(, 1, 2);
func(, , 1);

结果如下:

在这里插入图片描述

2.2 半缺省

2.2.1 错误用法示范

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)

结果如下:

在这里插入图片描述

2.没有连续地给出缺省值

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

在这里插入图片描述

2.2.2 正确用法示范

通过对比可以发现下面的这些全部满足【从右往左依次连续给出缺省值】,满足了若是前一个有缺省值后一个也连续的也必须有缺省值的条件

void func(int a, int b = 20, int c = 30)		//✔	后两个缺省
void func(int a, int b, int c = 30)				//✔	最后一个缺省

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

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一个值,可以看出编译器检查得严格,若是检查得不严格那么打印出来的就是一个随机值

在这里插入图片描述

2.第一、二形参无缺省,至少传入两个实参

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个实参,因为第三个形参有默认缺省值

在这里插入图片描述

3.三个形参均无缺省值,需传入三个实参

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 = ?

最后这一种,就是当所有的形参缺省值都没有给出的时候,此时就是我们写的正常函数形式,三个形参就必须传入三个实参,缺一不可

在这里插入图片描述

3. 缺省参数的规则和限制

  • 顺序要求:缺省参数必须从右向左定义,不能跳跃。如果函数中有多个参数,未缺省的参数必须在最左边。

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

在这里插入图片描述

  • 缺省值必须是常量或全局变量:缺省值必须是编译时已知的值,不能是局部变量或运行时动态计算的值。

这一点很好理解,你给出的缺省值必须是一个固定的值,而不是一个可修改的变量,否则这个缺省值将毫无意义;对于缺省值一般我们不会使用全局变量,因为全局变量会存在线程安全的问题,日常写代码也是不推荐使用全局变量。

  • C语言不支持(编译器不支持)。演示一下,创建了一个test.c的源文件的,然后和上面一样为这里的函数形参给到缺省值,接着去编译的话就可以发现是会出现很多错误的,这其实就可以看出C语言是不支持【缺省参数】的。

在这里插入图片描述

4. 规定必须函数声明给缺省值

缺省参数不能在函数声明和定义中同时出现,因为如果我们声明和定义如果默认参数不一致的话,我们应该听谁的呢?比如在声明中默认参数是4,而到了定义中默认参数是40,那到底默认参数是几呢?故缺省参数不能在函数声明和定义中同时出现。

那么缺省参数到底是声明给呢还式定义给呢?

1.首先我们先来看看缺少参数给定义是什么结果?

在这里插入图片描述

在这里插入图片描述

我们发现如果定义给的话报错了,主要问题就是函数不接受一个参数

✍首先在编译阶段的预处理阶段,在两个.cpp文件中展开.h头文件,两个.cpp文件在编译阶段各走各的(在链接阶段才会合到一起)。

这里出错是在编译阶段就报错了,因为我们包含的头文件是.h,而.h文件中只有声明没有定义而编译器在处理的时候发现一开始传参传了两个参数,后来就值传了一个参数,请看下图:

在这里插入图片描述

2.然后我们先来看看缺少参数给声明是什么结果?

在这里插入图片描述

这里我们发现程序是可以正常运行的,当编译器处理StackInit(&st1, 100);的时候按照正常传参即可(跟缺省参数没有什么关系);而当编译器处理StackInit(&st2);的时候,我们由于在声明中给了缺省,所以编译器在编译的时候,我们可以认为编译器会把StackInit(&st2);转换为StackInit(&st2,4);,所以对于函数定义而言根本不需要关心到底是不是缺省的,因为函数定义的时候都要传两个参数给它,所以声明调用的时候如果只有一个参数,会转换成两个参数。故缺省参数声明给而定义不给。

5. 缺省参数 vs 重载函数

在一些语言中,如Java,缺省参数并不被支持。为了模拟缺省参数的功能,通常通过重载函数来实现。例如:

int MyFunc(int a, int b) {
    return MyFunc(a, b, 12); // 缺省参数通过调用重载的函数实现
}
int MyFunc(int a, int b, int c) {
    // 主实现
}

虽然这也能达到类似效果,但代码较为冗余,缺省参数在C++中显然更加简洁易用。

6. 其它常见问题和注意事项

6.1 缺省参数的表达式计算时机

当缺省参数是一个表达式时,表达式的计算时机是编译时还是运行时需要注意。在C++中,缺省参数的值是在函数调用时计算的,而非函数声明时。这与Python中缺省参数的行为不同,Python会在模块加载时计算默认参数。

6.2 静态和可变参数问题

在Python等语言中,如果缺省参数是可变类型(如列表),则它会被静态分配,即在所有函数调用中共享这个参数。这会带来意外的副作用。为避免此问题,可以使用监视哨值(如None),并在函数内部进行初始化,例如:

 def f(a, b=None):
     b = b or []

结语

今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下。

也可以点点关注,避免以后找不到我哦!

Crossoads主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的动力!

在这里插入图片描述

参考:https://juejin.cn/post/7222274630396198971

https://developer.aliyun.com/article/1217073

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

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

相关文章

Gartner发布2024年中国基础设施战略技术成熟度曲线

Gartner于近日首次发布2024年中国基础设施战略技术成熟度曲线&#xff0c;该曲线收录的21项技术主要覆盖四大领域&#xff0c;分别是&#xff1a;自主可控计划、AI 影响、运营效率以及基础设施现代化。 Gartner研究总监张吟铃表示&#xff1a;“中国市场与全球市场虽然使用的技…

[Redis][预备知识]详细讲解

目录 1.命令1.最核心的两个命令1.SET2.GET3.说明 2.基本全局命令0.前言1.KEYS2.EXISTS3.DEL4.EXPIRE5.TTL6.TYPE 2.数据结构和内部编码3.单线程架构1.单线程模型2.单线程还效率高&#xff1f;(重点)3.注意 1.命令 1.最核心的两个命令 1.SET 语法&#xff1a;SET key value功…

jmeter发送邮件:详细步骤与功能配置指南?

jmeter发送邮件如何设置&#xff1f;怎么配置JMeter以发送邮件&#xff1f; Apache JMeter作为一款强大的性能测试工具&#xff0c;不仅可以用于测试Web应用的性能&#xff0c;还可以通过插件扩展其功能&#xff0c;实现诸如发送邮件等操作。AokSend将详细介绍如何使用JMeter发…

核心复现—计及需求响应的区域综合能源系统双层优化调度策略

目录 一、主要内容&#xff1a; 二、摘要介绍&#xff1a; 三、综合能源系统结构&#xff1a; 四、实际仿真运行结果&#xff1a; 五、代码数据下载&#xff1a; 一、主要内容&#xff1a; 在模型构建部分&#xff1a;建立了一个综合能源系统双层优化调度模型&#xff0c;…

openeuler22.03 LTS 源码编译安装fastdfs-6.06

openeuler22.03 LTS 源码编译安装fastdfs-6.06 1、环境 名称版本备注openeuler22.03 LTSfastdfs6.06libfastcommon1.0.43libfastcommon是一个开源的C语言库&#xff0c;用于实现高性能的分布式文件系统和分布式存储系统 2、准备安装包 fastdfs 官网&#xff1a; https://git…

《概率论与数理统计》学渣笔记

文章目录 1 随机事件和概率1.1 古典概型求概率随机分配问题简单随机抽样问题 1.2 几何概型求概率1.3 重要公式求概率 2 一维随机变量及其分布2.1 随机变量及其分布函数的定义离散型随机变量及其概率分布&#xff08;概率分布&#xff09;连续型随机变量及其概率分布&#xff08…

【machine learning-12-多元线性回归】

线性回归-多特征 多特征线性回归多特征表示更简单的多元线性回归表示方法 之前节的线性回归为简化都是用的单特征&#xff0c;但现实中我们的预测因素很复杂不可能只有一个特征&#xff0c;下面总结多特征线性回归 多特征 之前总是用房价举例&#xff0c;预测房价和房屋面积的…

个人量化成功之路-----从 Yahoo! Finance 下载交易策略数据

雅虎财经 是投资者最受欢迎的网站之一。它提供有关股票、债券、货币和加密货币的各种市场数据。它还提供市场新闻、报告和分析、期权和基本数据 官方的雅虎财经 API 于 2017 年被下架 Yfinance 是由 Ran Aroussi 开发的开源 Python 库&#xff0c;用于访问雅虎财经上可用的财…

基于微信小程序的宠物寄养平台的设计与实现+ssm(lw+演示+源码+运行)

摘 要 随着科技和网络的进步&#xff0c;微信小程序技术与网络、生活贴和的更加紧密。需要依靠客户端的单机系统逐渐被淘汰&#xff0c;利用互联网可以处理大量数据的新型系统如雨后春笋般迅速发展起来。这类系统和信息化时代的同步发展对传统的办公管理方式造成了很大的压力。…

C++进阶学习——模版进阶

1. 非类型模板参数 模板参数分类类型形参与非类型形参。 类型形参即&#xff1a;出现在模板参数列表中&#xff0c;跟在class或者typename之类的参数类型名称。 非类型形参&#xff0c;就是用一个常量作为类(函数)模板的一个参数&#xff0c;在类(函数)模板中可将该参数当成…

如何基于scrcpy改造实现大厂一键连招/触摸宏功能(带java源码)-千里马安卓framework实战

背景&#xff1a; 前面公众号文章已经分享过如何实现这种大厂里面一键连招&#xff0c;触摸宏的功能&#xff0c;原理本身是对dev/input下面的节点进行读取保存文件&#xff0c;然后在读取文件进行写入dev/input下面的节点&#xff0c;从而实现了触摸事件的读取和写入&#xf…

OpenMVG试用

1 OpenMVG 简介 全称 Open Multiple View Geometry&#xff0c;是法国人 Pierre Moulon 读博期间开源的一个 C 库 最早版本 OpenMVG 0.1 是 2013年 2月 发布的&#xff0c;目前最新版本是 2021年 10月 发布的 OpenMVG 2.0 LinkedIn 显示&#xff0c;此前一直在…

docker存储

docker分层结构 如图所示&#xff0c;容器是由最上面可读可写的容器层&#xff0c;以及若干个只读镜像层组成&#xff0c;创建容器时&#xff0c;容器中的 数据都来自镜像层。这样的分层机构最大的特点是写时复制&#xff1a; 1、容器中新生成的数据会直接存放在容器层&#xf…

8. 防火墙

8. 防火墙 (1) 防火墙的类型和结构 防火墙的类型和结构可以根据其在网络协议栈中的过滤层次和实现方式进行分类。常见的防火墙类型包括: 包过滤防火墙:工作在网络层(OSI模型的第3层),主要检查IP包头的信息,如源地址、目的地址、端口号等。电路级网关防火墙:工作在会话层…

初始MYSQL数据库(6)—— 事务

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; MYSQL 目录 事务的概念 事务的ACID特性 使用事务 查看支持事务的存储引擎 事务的语法 保存点 自动/手动提交事务 事务的隔离性和…

NLP 文本分类任务核心梳理

解决思路 分解为多个独立二分类任务将多标签分类转化为多分类问题更换 loss 直接由模型进行多标签分类 数据稀疏问题 标注更多数据&#xff0c;核心解决方案&#xff1a; 自己构造训练样本 数据增强&#xff0c;如使用 chatGPT 来构造数据更换模型 减少数据需求增加规则弥补…

MySQL --基本查询(下)

文章目录 3.Update3.1将孙悟空同学的数学成绩变更为 80 分3.2将曹孟德同学的数学成绩变更为 60 分&#xff0c;语文成绩变更为 70 分3.3将总成绩倒数前三的 3 位同学的数学成绩加上 30 分3.4将所有同学的语文成绩更新为原来的 2 倍 4.Delete4.1删除数据4.1.1删除孙悟空同学的考…

learn C++ NO.19——二叉搜索树

简单介绍一下二叉搜索树 二叉搜索树也称为二叉排序树。它是一种具有特殊性质的二叉树。它有如下性质。 1、当前节点的左子树的值一定小于当前节点&#xff0c;当前节点的右子树的值一锭大于当前节点。这也就意味着&#xff0c;在接近完全二叉树的情况下&#xff08;高度较为合…

开源实时多模态AI聊天机器人Moshi,语音对话延迟低至200毫秒!

开源实时多模态AI聊天机器人Moshi&#xff0c;语音对话延迟低至200毫秒&#xff01; 最近AI圈真是热闹非凡&#xff0c;继Meta发布Llama 3之后&#xff0c;各种开源大模型也是层出不穷。这不&#xff0c;法国一个非盈利AI研究实验室Kyutai&#xff0c;又搞了个大新闻&#xff0…

从零到一:如何用Ollama和OpenUI构建强大的AI模型库

搭建开源大模型平台的步骤与模型介绍 在这篇文章中&#xff0c;我将分享如何在Windows上使用Ollama和OpenUI搭建开源大模型平台的步骤&#xff0c;并介绍我所部署的几个模型及其擅长的领域。 目录 搭建开源大模型平台的步骤与模型介绍一、搭建平台步骤1. 安装Ollama2. 安装Ope…