C++从入门到精通——缺省参数

缺省参数

  • 前言
  • 一、缺省参数概念
  • 二、缺省参数分类
    • 位置参数的缺省参数
      • 全缺省参数
      • 半缺省参数
    • 关键字参数的缺省参数
    • 函数指针的缺省参数
      • `lambda`表达式
  • 三、缺省参数的具体代码展示
    • main.cpp


前言

缺省参数是在函数定义时指定的默认值,当调用函数时未提供该参数的值时,将使用缺省值。使用缺省参数可以简化函数调用,提高代码可读性。但需注意,过多使用缺省参数可能导致代码难以理解和维护。


一、缺省参数概念

缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。这种机制允许函数在更广泛的情境下被调用,提高了代码的灵活性和可重用性。

在许多编程语言中,如Python、Java和C++等,都支持缺省参数的概念。下文将以C++为例,通过在函数定义时为某些参数指定默认值,就可以创建出可以接受可变数量参数的函数。这样,当调用者只提供了部分参数时,函数依然可以正确地执行,而那些没有提供值的参数则会使用默认值。

这种设计不仅方便了开发者,也使得代码更加易于理解和维护。因为当函数有多个参数时,如果每个参数都必须明确提供,那么调用者就需要记住每个参数的意义和顺序,这无疑增加了出错的概率。而有了缺省参数,即使调用者忘记了某个参数的值,函数也能正常工作,只是使用了预设的默认值而已。

此外,缺省参数还有助于实现函数的重载。在某些语言中,虽然不直接支持函数重载(即多个同名函数,但参数列表不同),但可以通过结合缺省参数和可变参数来实现类似的效果。这样,就可以根据调用者提供的参数数量和类型,执行不同的函数逻辑。

ps:关于函数重载,我将在下篇文章详细讲解

然而,虽然缺省参数带来了很多便利,但使用时也需要谨慎。过多的缺省参数可能导致函数的行为变得难以预测,因为调用者可能不清楚哪些参数使用了默认值,哪些参数是明确提供的。因此,在设计函数时,应该合理地选择哪些参数应该有默认值,哪些参数应该是必须的。

#include<iostream>
using namespace std;
void Func(int a = 0)
{cout << a << endl;
}
int main()
{Func();     // 没有传参时,使用参数的默认值Func(10);   // 传参时,使用指定的实参return 0;
}

在这里插入图片描述

二、缺省参数分类

缺省参数分类是程序设计中常见的一种参数设置方式。它允许在函数调用时省略某些参数,这些参数会使用预设的默认值。缺省参数可以分为两类:位置缺省参数和关键字缺省参数。位置缺省参数根据函数参数列表中的顺序确定默认值,而关键字缺省参数则通过指定参数名来设置默认值。这种分类方式有助于简化函数调用,提高代码的可读性和灵活性。

在 C++ 中可以分为以下几种类型:

位置参数的缺省参数

全缺省参数

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

在这里插入图片描述

半缺省参数

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

在这里插入图片描述

如果参数不够就会报错
在这里插入图片描述

注意

  1. 半缺省参数必须从右往左依次来给出,不能间隔着给
  2. 缺省参数不能在函数声明和定义中同时出现
//a.hvoid Func(int a = 10);// a.cppvoid Func(int a = 20){}// 注意:如果生命与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该用哪个缺省值。
  1. 缺省值必须是常量或者全局变量
  2. C语言不支持(编译器不支持)

关键字参数的缺省参数

在函数的参数列表中使用关键字参数,并为其设置默认值。调用函数时可以不传入这些参数,而是使用默认值。

void greet(string name, string message = "Hello") {  // message 是缺省参数,设定默认值为 "Hello"cout << message << ", " << name << endl;
}greet("Alice");  // 输出 "Hello, Alice"
greet("Bob", "Good morning");  // 输出 "Good morning, Bob"

在这里插入图片描述

函数指针的缺省参数

对于C++函数指针不理解的地方,可看作者的后续文章

在函数的参数列表中可以设置一个函数指针作为参数,并为其设置默认值。

void printNumber(int num) {cout << num << endl;
}void processNumber(int num, void (*func)(int) = printNumber) {func(num);
}processNumber(123);  // 输出 123
processNumber(456, [](int num) { cout << "Number: " << num << endl; });  // 输出 "Number: 456"

关于

processNumber(456, [](int num) { cout << "Number: " << num << endl; });  // 输出 "Number: 456"

这段代码定义了一个名为processNumber的函数,该函数有两个参数:一个整数num和一个函数指针。函数指针指向一个没有返回值的函数,该函数接受一个整数作为参数,并在函数体内打印出该整数。

 [](int num) { cout << "Number: " << num << endl; }

上述代码是个空函数,后面大括号里的是这个空函数里的代码,只不过是放在同一排上,正常应如下,这种叫lambda表达式,可以按照我说的方式来理解

{cout << "Number: " << num << endl; 
}

当调用processNumber函数时,传入的第一个参数是456,第二个参数是一个lambda表达式,这个lambda表达式定义了一个匿名函数,其参数为一个整数num,函数体内打印出"Number: "加上num的值,然后换行。

因此,调用processNumber(456, [](int num) { cout << "Number: " << num << endl; });的结果将是打印出"Number: 456"
在这里插入图片描述

需要注意的是,在 C++ 中,缺省参数只能从右到左连续出现,即在参数列表中,缺省参数必须位于非缺省参数的右侧。

lambda表达式

在C++中,lambda表达式被用于创建匿名函数。它的语法与其他编程语言中的lambda表达式相似。

在C++中,lambda表达式的语法为:

[capture list](parameters) -> return_type {// 函数体
}

其中,capture list是可选的,用于捕获外部变量,可以是空的或包含一个或多个外部变量。parameters是函数的参数列表,可以为空。return_type是函数的返回类型,可以省略或使用auto自动推导。

下面是一个示例,使用lambda表达式定义一个函数,打印输入的数字:

void processNumber(int num, const std::function<void(int)>& callback) {callback(num);
}int main() {int num = 456;processNumber(num, [](int num) { std::cout << "Number: " << num << std::endl; });return 0;
}

在上面的示例中,processNumber函数接受一个数字和一个callback函数作为参数。callback是一个std::function类型,其中的参数为int类型。在main函数中,我们使用lambda表达式作为回调函数,打印输入的数字。

三、缺省参数的具体代码展示

main.cpp

#include<iostream>
using namespace std;
//void Func(int a = 0)
//{
//	cout << a << endl;
//}//void Func(int a = 10, int b = 20, int c = 30)
//{
//	cout << "a = " << a << endl;
//	cout << "b = " << b << endl;
//	cout << "c = " << c << endl;
//}
void Func(int a, int b = 10, int c = 20)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl;
}
void greet(string name, string message = "Hello") {  // message 是缺省参数,设定默认值为 "Hello"cout << message << ", " << name << endl;
}
void printNumber(int num) {cout << num << endl;
}void processNumber(int num, void (*func)(int) = printNumber) {func(num);
}int main()
{//Func();     // 没有传参时,使用参数的默认值//Func(10);   // 传参时,使用指定的实参//Func();/*Func(60);Func(50,100);*///greet("Alice");  // 输出 "Hello, Alice"//greet("Bob", "Good morning");  // 输出 "Good morning, Bob"processNumber(123);  // 输出 123processNumber(456, [](int num) { cout << "Number: " << num << endl; });  // 输出 "Number: 456"return 0;
}

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

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

相关文章

暴雨服务器X7740赋能大模型训练

数字经济浪潮愈演愈烈,大模型训练对服务器的要求也越来越高。在此背景下,暴雨信息发布专门为大规模模型训练而设计的全新旗舰GPU服务器—X7740,以卓越的计算性能、高速网络通信能力以及创新的能效表现,有效赋能大模型训练。 X7740 搭载了暴雨信息最新一代的英特尔至强可扩展处理…

如何划分训练集、测试集、验证集

训练集、测试集和验证集是在机器学习和数据科学中常用的术语&#xff0c;用于评估和验证模型的性能。它们通常用于监督学习任务中。 1. 训练集&#xff08;Training Set&#xff09;&#xff1a;训练集是用于训练机器学习模型的数据集。在训练期间&#xff0c;模型使用训练集中…

Leetcode - 周赛390

目录 一&#xff0c;3090. 每个字符最多出现两次的最长子字符串 二&#xff0c;3091. 执行操作使数据元素之和大于等于 K 三&#xff0c;3092. 最高频率的 ID 四&#xff0c;3093. 最长公共后缀查询 一&#xff0c;3090. 每个字符最多出现两次的最长子字符串 本题是一道标准…

嵌入式C语言中头文件计设规则方法

我是阿梁,最近在负责的项目代码,也算是祖传代码了,里面有很多头文件嵌套的情况,即a.h包含b.h,b.h又包含c.h,c.h又包含d.h......遂找到一份华子的C语言编程规范学习一下,并结合自己的理解写成这篇文章,以规范自己的代码。 1. 头文件嵌套的缺点 依赖:若x.h包含了y.h,则…

启信宝商业大数据助力全国经济普查

近日&#xff0c;合合信息旗下启信宝收到中国青年创业就业基金会感谢信&#xff0c;对启信宝协同助力全国经济普查和服务青年创业就业研究表达感谢。 第五次全国经济普查是新时代新征程上一次重大国情国力调查&#xff0c;是对国民经济“全面体检”和“集中盘点”&#xff0c;…

武汉星起航:亚马逊受惠国家政策,企业成长与行业发展齐头并进

亚马逊电商平台作为国际知名的跨境电商巨头&#xff0c;在中国市场也展现出了强劲的发展势头。近年来&#xff0c;国家政策对亚马逊电商平台的支持力度不断加大&#xff0c;为企业提供了良好的发展环境和机遇。武汉星起航将探讨国家政策对亚马逊电商平台的重要影响&#xff0c;…

深度思考:雪花算法snowflake分布式id生成原理详解

雪花算法snowflake是一种优秀的分布式ID生成方案&#xff0c;其优点突出&#xff1a;它能生成全局唯一且递增的ID&#xff0c;确保了数据的一致性和准确性&#xff1b;同时&#xff0c;该算法灵活性强&#xff0c;可自定义各部分bit位&#xff0c;满足不同业务场景的需求&#…

QT使用数据库

数据库就是保存数据的文件。可以存储大量数据&#xff0c;包括插入数据、更新数据、截取数据等。用专业术语来说&#xff0c;数据库是“按照数据结构来组织、存储和管理数据的仓库”。 什么时候需要数据库&#xff1f;在嵌入式里&#xff0c;存储大量数据&#xff0c;或者记录数…

【项目技术介绍篇】若依开源项目RuoYi-Cloud后端技术介绍

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过大学刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0…

双端队列deque和vector以及list的优缺点比较

参考:https://blog.csdn.net/TWRenHao/article/details/123483085 一、vector vector具体用法详情点这里 优点&#xff1a; 支持随机访问 CPU高速环缓存命中率很高 缺点&#xff1a; 空间不够&#xff0c;便需要增容。而增容代价很大&#xff0c;还存在一定的空间浪费。 头部…

在同一个网站上自动下载多个子页面内容

一、问题现象 第一次遇到这样的问题&#xff0c;如下图&#xff1a; 即在同一个网站上下载多个内容时&#xff0c;第一个内容明明已经正常get到了&#xff0c;但开始第二个页面的查询 以后&#xff0c;原来已经查出的内容就找不到了。 二、解决办法 我不知道大家是不是遇到…

C++项目——集群聊天服务器项目(七)Model层设计、注册业务实现

在前几节的研究中&#xff0c;我们已经实现网络层与业务层分离&#xff0c;本节实现数据层与业务层分离&#xff0c;降低各层之间的耦合性&#xff0c;同时实现用户注册业务。 网络层专注于处理网络通信与读写事件 业务层专注于处理读写事件到来时所需求的各项业务 数据层专…

msvcr110.dll文件丢失要怎么办?教你多种解决msvcr110.dll文件的方法

面对“程序无法启动&#xff0c;因为电脑中缺失msvcr110.dll”的错误提示&#xff0c;你可能会觉得你的工作或者休闲时间被意外中断了&#xff0c;这确实很让人烦恼。这种问题对于很多Windows用户来说并不陌生&#xff0c;但幸运的是&#xff0c;它通常可以通过几个简单的步骤得…

node.js学习(2)

版权声明 以下文章为尚硅谷PDF资料&#xff0c;B站视频链接&#xff1a;【尚硅谷Node.js零基础视频教程&#xff0c;nodejs新手到高手】仅供个人学习交流使用。如涉及侵权问题&#xff0c;请立即与本人联系&#xff0c;本人将积极配合删除相关内容。感谢理解和支持&#xff0c;…

Python3:ModuleNotFoundError: No module named ‘elftools‘

问题背景 问题 ModuleNotFoundError: No module named ‘elftools’ 解决方法 pip3 install pyelftools 成功&#xff01;&#xff01;&#xff01;

哲♂学家带你深♂入理解c语言的编译与链接

目录 前言&#xff1a; 一、翻译环境 二、预处理 三、编译 1.词法分析 2.语法分析 3、语义分析 四、汇编 五、链接 总结&#xff1a; 前言&#xff1a; 编译和链接能够帮我们更好的理解c语言中程序执行前是如何运行的&#xff0c;今天由本哲学家带你深入理解c语言的编译…

iOS - Runloop的运行逻辑

文章目录 iOS - Runloop的运行逻辑1. 苹果官方的Runloop执行图2. Mode里面的东西2.1 Source02.2 Source12.3 Timers2.4 Observers 3. 执行流程3.1 注意点 4. Runloop休眠 iOS - Runloop的运行逻辑 1. 苹果官方的Runloop执行图 2. Mode里面的东西 2.1 Source0 触摸事件处理pe…

Unity Mesh 生成图形(一)

目录 一、概述 二、获取顶点坐标和索引 三、绘制正方形 1.显示顶点坐标 2.顶点坐标的顺序 3.顶点排序 4.绘制最终效果 结束 一、概述 Unity 的 Mesh 是用于表示三维物体的网格数据结构。它是由一系列顶点和三角形组成的网格&#xff0c;用于描述物体的形状和外观。 M…

Java8之接口默认方法

Java8之接口默认方法 一、介绍二、代码1、接口2、实现类3、测试代码4、效果 一、介绍 在Java8中&#xff0c;允许为接口方法提供一个默认的实现。必须用default修饰符标记这样一个方法。默认方法也可以调用其他方法 二、代码 1、接口 public interface PersonService {void…

python 进程、线程、协程基本使用

1、进程、线程以及协程【1】进程概念【2】线程的概念线程的生命周期进程与线程的区别 【3】协程(Coroutines) 2、多线程实现【1】threading模块【2】互斥锁【3】线程池【4】线程应用 3、多进程实现4、协程实现【1】yield与协程【2】asyncio模块【3】3.8版本【4】aiohttp 1. 并发…