C++ -缺省参数-详解
博客主页:【夜泉_ly】
本文专栏:【C++】
欢迎点赞👍收藏⭐关注❤️
C++ -缺省参数-详解
- 1.是什么
- 2.分类
- 2.1全缺省参数
- 2.2半缺省参数:
- 3.实际应用
- 4.关于缺省参数的声明与定义
- 5.总结
1.是什么
先来看看下面这段代码:
#include <stdio.h>
void func(int i = 0)
{
printf("%d\n", i);
}
int main()
{
func();
return 0;
}
如果是在C语言中,那么编译器毫无疑问会报错:
首先,C语言不支持在参数列表中初识化参数:
其次,C语言不支持少传参数:
但是,如果将这段代码放在.cpp
中再运行,就会输出结果:
0
这就是今天我要讲的缺省参数(也叫默认参数)。
其规则大致如下:
func(); //没有传参时,使用默认值。
func(1);//有传参时,使用指定的实参。
2.分类
2.1全缺省参数
当一个函数的所有参数都是缺省参数时,称为全缺省参数:
void func(int a = 0, int b = 0, int c = 0)
{
printf("a = %d\n", a);
printf("b = %d\n", b);
printf("c = %d\n", c);
printf("\n");
}
使用:
- 不传参时,使用所有参数的默认值
运行结果:func();
0 0 0
- 只传第一个参数
运行结果:func(1);
1 0 0
- 传前两个参数
运行结果:func(1,2);
1 2 0
- 传三个参数
运行结果:func(1,2,3);
1 2 3
不可以跳着传!!
为什么?
因为祖师爷本贾尼·斯特劳斯特卢普没有这样规定。
2.2半缺省参数:
void func(int a, int b = 0,int c = 0)
{
printf("a = %d\n", a);
printf("b = %d\n", b);
printf("c = %d\n", c);
}
这种情况,至少要传入a
的参数。
而 b
和 c
可以选择是否传递,如果不传递,函数会使用默认值。
注意:
-
缺省从右往左
如果像这样定义:void func(int a = 0, int b = 0, int c) { printf("a = %d\n", a); printf("b = %d\n", b); printf("c = %d\n", c); }
那么只传一个参数时究竟是传给
a
还是c
,这里会引发歧义。
并且,这样的写法编译器会直接报错:
-
传参从左往右
道理与上面类似,传参不能跳过左边的,因为也会引发歧义。
因此,在使用缺省参数时有一个必须注意的点:避免产生歧义!
3.实际应用
在栈的初始化过程中,经常面临“小了不够,大了浪费”的问题。
void StackInit(Stack* s)
{
assert(s);
s->a = (StackDataType*)malloc(sizeof(StackDataType) * 4);
if (!s->a)
{
perror("InitStack::malloc");
return;
}
s->top = 0;
s->capacity = 4;
}
此处的函数默认初始化的大小为4。
但如果已经知道了要插入100个数据,那么每次都扩容会很麻烦,且效率不高。
或许可以传入想要初始化的大小:
StackInit(&Stack1,100);
但如果不知道要插入多少数据呢?
这样就再次遇到“小了不够,大了浪费”的问题😂。
此时,缺省参数就能派上用场了:
void StackInit(Stack* s,int default_capacity = 4)
- 默认开小一点,避免空间浪费
- 也可以自己传参,减少扩容次数。
而在C语言中,往往会这样解决这个问题:
#define DEFAULT_CAPACITY 4
但这样的解决方法,不能做到下面这种操作:
StackInit(&Stack1,100);//使用给定值100
StackInit(&Stack2); //使用默认值4
因此,缺省参数更加灵活👍。
4.关于缺省参数的声明与定义
一个常见的疑问是:
声明、定义都给缺省参数,还是只给一个?
为了解释这个问题,我创建了三个文件:
func.h
:
#pragma once
#include <stdio.h>
void func(int a = 0);
func.c
:
#include "func.h"
void func(int a = 0)
{
printf("%d\n", a);
}
test.c
:
#include "func.h"
int main()
{
func();
return 0;
}
如果都给,如上面代码所示,运行结果如下:
报错:重定义默认参数(即缺省参数)。
这说明不允许都给,为什么呢?
因为这样可以避免声明和定义中缺省参数不同的可能。
那么是在声明中给缺省参数,还是在定义中给?
定义中给,运行结果如下:
报错:函数不接受0个参数。
这说明参数传少了,为什么?
在预处理阶段,头文件会展开,编译时,每个 .c
或 .cpp
文件都是独立编译的,直到链接阶段才会被链接在一起。
而查看语法是在编译阶段进行,此时还没有链接在一起,而在声明中没有缺省参数,传参时又少传了参数,因此编译器会报错。
因此,在声明中给出缺省参数可以确保编译时正确识别:
//展开的头文件:
#pragma once
#include <stdio.h>
void func(int a = 0);
//test.cpp:
int main()
{
func(); //-->func(0);
return 0;
}
因此,在声明中给缺省参数,在定义中不给。
5.总结
通过上述例子和讨论,可以看到,C++ 缺省参数是一种非常有用的功能,它极大地提高了代码的灵活性和可读性。
使用缺省参数可以简化函数调用,避免冗余代码,并且使得代码更加易于维护。
通过合理设置缺省参数,可以更好地应对实际编程中的各种需求,提高程序的健壮性和实用性。
希望本篇文章对你有所帮助!并激发你进一步探索编程的兴趣!
本人仅是个C语言初学者,如果你有任何疑问或建议,欢迎随时留言讨论!让我们一起学习,共同进步!