博客主页:【夜泉_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();
运行结果:000
只传第一个参数func(1);
运行结果:100
传前两个参数func(1,2);
运行结果:120
传三个参数func(1,2,3);
运行结果:123
不可以跳着传!!
为什么?
因为祖师爷本贾尼·斯特劳斯特卢普没有这样规定。
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);//使用给定值100StackInit(&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语言初学者,如果你有任何疑问或建议,欢迎随时留言讨论!让我们一起学习,共同进步!