首页 > 编程语言 >C++从入门到精通——缺省参数

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

时间:2024-03-29 16:01:34浏览次数:35  
标签:函数 int cout 缺省 C++ 参数 默认值 入门

缺省参数


前言

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


一、缺省参数概念

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

在许多编程语言中,如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.h
  void Func(int a = 10);
  
  // a.cpp
  void 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);  // 输出 123
	processNumber(456, [](int num) { cout << "Number: " << num << endl; });  // 输出 "Number: 456"
	return 0;
}


标签:函数,int,cout,缺省,C++,参数,默认值,入门
From: https://blog.csdn.net/qq_74013365/article/details/137142138

相关文章

  • JavaScript快速入门笔记之七(String:字符串类型、RegExp:正则表达式)
    JavaScript快速入门笔记之七(String:字符串类型、RegExp:正则表达式)String:字符串类型什么是字符串?底层本质:一串字符组成的只读字符数组包装类型:临时封装原始类型数据,并提供对数据操作方法的对象——类型名和原始类型名相同!StringNumberBoolean何时使用:不必手动创建!......
  • c++基础知识
    deque的用法#include<deque>deque<type>d;//定义一个dequepush_back()//在队列的尾部插入元素。push_front()//在队列的头部插入元素。pop_back()//删除队列尾部的元素。pop_front()//删除队列头部的元素。back()//返回队列尾部元素的引用。front()//返回队列头部元素......
  • C++继承、多态代码备忘录
    HelloWorld#include<iostream>//Basedon64-bitmachines.//1.SizeofABCis16bytes,8bytesforvptr,1byteforchara,7bytes//padding.//2.ThevptrpointtothevtableofABC,thevtablecontainstheaddressof//thevirtualfunct......
  • c++类,汽车信息
    #include<iostream>#include<string>usingnamespacestd;class Car{private:      string brand;   stringmodel;   stringcolor;public:   voidcar(stringbrand,stringmodel,stringcolor)   //voidcar()括号里要有形参,不......
  • podman 入门实战
     一入编程深似海,从此节操是路人。最近使用podman,就想着写一篇总结性的笔记,以备后续参考。就如同写代码,不写注释,过了一段时间可能会想这是我写的吗?不会吧,还要理一下逻辑才能读懂,不利于后期维护。感觉整体体验下来,镜像获取、容器创建、容器监控、容器移除,和docker差不多,感觉可......
  • Effective C++ 导论
    芝士wa2024.3.29EffectiveC++.pdf“本书的目的在于引导你如何高效使用C++”本书的研究范围:标准的设计策略特殊语言特性的具体细节例如:如何在inheritance(继承)和templates(模板)之间选择?如何在public(公有)和privateinheritance(私有继承)之间选择?如何在member(成员......
  • Bootloader/IAP零基础入门(1.1) —— 设计一个Bootloader引导进入APP的程序,包含中断向量
    前言(1)如果有嵌入式企业需要招聘湖南区域日常实习生,任何区域的暑假Linux驱动/单片机/RTOS的实习岗位,可C站直接私聊,或者邮件:[email protected],此消息至2025年1月1日前均有效(2)在上一章节中,我们详细介绍了如何让Bootloader引导进入APP程序。但是上一章节的工程是无法使用......
  • C++17: 结构化绑定(Structured Bindings)
    遇到有时候写函数需要返回多个值的情况。C++17之前,只能事先定义一个结构体,然后返回这个结构体类型就可以了。但是如果你的这个结构体类型只在这个这里用一次呢。你还要抠脑壳想一个合适的结构体名字,麻烦!std::tupleC++11引入了一个新的类模板叫std::tuple,是一个容器,可以......
  • 《责任链模式(极简c++)》
            本文章属于专栏-概述-《设计模式(极简c++版)》-CSDN博客模式说明方案:责任链模式将请求的发送者和接收者解耦,构成一个链条,并由多个对象对请求进行处理,直到找到合适的处理者为止。优点:实现了请求发送者和接收者的解耦,灵活性高,易于扩展,每个处理者只需关注自......
  • 《代理模式(极简c++)》
            本文章属于专栏-概述-《设计模式(极简c++版)》-CSDN博客模式说明方案:代理模式充当了客户端和实际对象之间的中介,通过引入代理对象来控制对原始对象的访问。优点:通过代理,可以实现对目标对象的控制,提供更多的功能,例如延迟加载、访问控制、日志记录等。缺点......