21天学会C++:Day3----缺省参数

· CSDN的uu们,大家好。这里是C++入门的第三讲。
· 座右铭:前路坎坷,披荆斩棘,扶摇直上。
· 博客主页: @姬如祎
· 收录专栏:C++专题

9a48d4540c9642eea8788c941c76a783.gif

目录

1. 知识引入

2. 缺省参数知识点

2.1 全缺省

2.2 半缺省

2.3 函数定义给缺省值还是函数声明给缺省值

2.4 小小的补充


 

1. 知识引入

还记得我们在用C语言实现栈的时候不是给了一个默认的栈的大小吗?当时我们使用的是#define定义标识符,然后初始化栈的时候,我们就会使用这个标识符来初始化栈的大小。

#define STACK_INIT_SIZE 4

struct Stack
{
	int* a;
	int size;
	int capacity;
};

void StackInit(struct Stack* st)
{
	assert(st);
	st->a = (int*)malloc(sizeof(int) * STACK_INIT_SIZE);
	if (st->a == NULL)
	{
		perror("StackInit::malloc");
		exit(-1);
	}
	st->size = 0;
	st->capacity = STACK_INIT_SIZE;
}

我们可以看到这个代码有一个明显的缺陷,就是如果说我们一旦指定了 STACK_INIT_SIZE 的大小之后,后续就无法进行更改了。一旦我们想创建不同初始大小的栈,C语言的这种写法就无法满足我们的需求。因此C++引入了缺省参数的概念。

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

我们先来看有了缺省参数的好处:有了缺省参数,在调用StackInit函数时我们可以不传参,默认开辟4个大小的空间。也可以指定传defaultCapacity,这样就可以实现栈不同的初始大小。

struct Stack
{
	int* a;
	int size;
	int capacity;
};

void StackInit(struct Stack* st, int defaultCapacity = 4)
{
	assert(st);
	st->a = (int*)malloc(sizeof(int) * defaultCapacity);
	if (st->a == NULL)
	{
		perror("StackInit::malloc");
		exit(-1);
	}
	st->size = 0;
	st->capacity = defaultCapacity;
}

int main()
{
	struct Stack st1;
	StackInit(&st1); //创建一个初始大小为4的栈

	struct Stack st2;
	StackInit(&st2, 100); //创建一个初始大小为100的栈

	return 0;
}

2. 缺省参数知识点

再来看看缺省参数的定义:

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

2.1 全缺省

我们会想,可以把函数的参数全部都设置一个缺省值吗?当然是可以的哦!我们称之为全缺省。

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

int main()
{
	func();
	func(1);
	func(1, 2);
	func(1, 2, 3);
}

既然是全缺省,就会上面这么多种调用函数的方式。

但是,这里我就想发问了:我们部分传参的时候,实参与形参的匹配顺序是怎样的呢?

比如:func(1, 2) 的输出结果是什么呢?答案是:1 2 30 。实参会从左向右去与形参进行匹配。

2.2 半缺省

所谓的半缺省就是,只有一部分参数是给了缺省值的。比如下面的代码:

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

int main()
{
	func(1);
	func(1, 2);
	func(1, 2, 3);
}

上面在全缺省是我们提到了:实参会从左向右依次去匹配形参。那么我们就能够得出结论:半缺省参数必须从右往左依次来给出,不能间隔着给。

e17938c706964fe9a8306dc36e83a553.png

2.3 函数定义给缺省值还是函数声明给缺省值

这里我想发问了:为什么不能函数声明与定义同时给缺省值呢?我们来看下面的代码:

我们将函数定义与函数声明的缺省值设置为不同的常量。

void func(int a = 10); //函数声明
void func(int a = 20) //函数定义
{
	cout << a << " " << endl;
}

int main()
{
	func();
	return 0;
}

运行之后会报错:

 5debaacf4a02463aaff9acdfdc078304.png

 你在函数定义与函数声明同时给缺省值,缺省值不一样的时候它到底听谁的呢?还有就是就算缺省值一样,编译也不能通过,(VS2019)编译器已经禁止了这种行为。

那到底是函数定义给,还是函数声明给呢?这就得联系编译链接的知识了。

我们将函数的定义与函数的声明分文件编写,先看看代码:

/
//test.h 中的代码

void func(int a = 20); //函数的声明


//test.cpp中的的代码

void func(int a) //函数的定义
{
    cout << a << endl;
}


//main.cpp 中的代码

#include "test.h"
#include<iostream>
using namespace std;

int main()
{
    func();
    return 0;
}

这里的结论就是,缺省值需要在函数声明给。编译链接大致分为预处理,编译,汇编,链接四个阶段。在预处理阶段,主要执行头文件的展开,宏的替换,条件语句的确定······,然后头文件就不会存在了。每个源文件会分别,各自编译。在main.cpp编译时,经过预处理阶段头文件的展开,在main.cpp中就会有func函数的声明:void func(int a = 20); 在main函数调用 func() 处,编译器就会将这条语句理解为 func(20),那么main.cpp的编译就没有问题。

如果我们是在函数的定义里面给缺省值,那么在main.cpp编译过程中,函数的定义就会是这样的:void func(int a),在main函数调用 func() 处就会报错:func()不接受0个参数,即无法编译成功。

e08d2f15c4cd4c65a7b7c7e054cf8beb.png

 这里的C2660中的C就是英文单词Compile (编译) 的缩写,即编译阶段报的错误。

因此,我们可以得出结论:缺省参数能且只能在函数声明的时候给。

2.4 小小的补充

函数形参的缺省值可以是全局变量,也可以是常量。

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

b85f2a6a7bb6423fa0d1f2d4240587a7.gif

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姬如祎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值