【C++初阶】缺省参数(默认参数)详细讲解

文章目录

  • 前言
  • 一、核心概念
  • 二、缺省参数的两大分类
    • [1. 全缺省参数](#1. 全缺省参数)
    • [2. 半缺省参数](#2. 半缺省参数)
  • [三、缺省参数 4 条硬性规则(重点!!!)](#三、缺省参数 4 条硬性规则(重点!!!))
    • [规则 1:半缺省必须「从右往左、连续」缺省](#规则 1:半缺省必须「从右往左、连续」缺省)
    • [规则 2:调用时实参必须「从左往右、依次」传参](#规则 2:调用时实参必须「从左往右、依次」传参)
    • [规则 3:声明与定义分离 → 缺省值只写在声明中](#规则 3:声明与定义分离 → 缺省值只写在声明中)
    • [规则 4:缺省值只能是「常量 / 全局变量」](#规则 4:缺省值只能是「常量 / 全局变量」)
  • 四、缺省参数的实际应用场景
  • 总结

前言

缺省参数 (有些地方也叫默认参数)是 C++ 在 C 语言基础上新增的核心语法特性,能让函数调用更灵活、代码更简洁。


一、核心概念

缺省参数 :在声明或定义函数 时,为函数的形参指定一个默认值。调用函数时遵循两个规则:

  1. 传入实参 → 使用传入的实参;
  2. 未传入实参 → 使用参数的默认值。

简单理解:调用函数时,没传的参数自动用预设的默认值补上。

二、缺省参数的两大分类

根据参数是否全部指定默认值 ,分为全缺省参数半缺省参数

1. 全缺省参数

函数的所有形参都设置默认值,调用时可以:不传参、传部分参、传全部参。

cpp 复制代码
#include <iostream>
using namespace std;

// 全缺省:所有参数都有默认值
void Func1(int a = 10, int b = 20, int c = 30)
{
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl << endl;
}

int main()
{
	Func1();          // 不传参:全部用默认值 a=10,b=20,c=30
	Func1(1);         // 传1个参:a=1,b=20,c=30
	Func1(1, 2);      // 传2个参:a=1,b=2,c=30
	Func1(1, 2, 3);   // 传3个参:全部用实参 a=1,b=2,c=3
	return 0;
}

2. 半缺省参数

函数的部分形参 设置默认值,必须从右往左连续指定,不能间隔、不能从左往右缺。

cpp 复制代码
#include <iostream>
using namespace std;

// 半缺省:从右往左连续缺省(a无默认,b、c有默认)
void Func2(int a, int b = 10, int c = 20)
{
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl << endl;
}

int main()
{
	Func2(100);          // 只传a:b=10、c=20(默认值)
	Func2(100, 200);     // 传a、b:c=20(默认值)
	Func2(100, 200, 300);// 传全部参数
	return 0;
}

禁止的半缺省写法(编译报错):

cpp 复制代码
// 错误1:从左往右缺,违反连续规则
void Func(int a = 10, int b = 20, int c) {}

// 错误2:间隔缺省,不连续
void Func(int a = 10, int b, int c = 20) {}

三、缺省参数 4 条硬性规则(重点!!!)

违反以下规则会直接导致编译报错

规则 1:半缺省必须「从右往左、连续」缺省

只能从最右侧参数 开始,向左依次设置默认值,不能跳跃、不能从左开始

规则 2:调用时实参必须「从左往右、依次」传参

调用函数时不能跳跃传参,必须从第一个参数开始依次传入。

cpp 复制代码
Func1( , 2, 3); // 错误:不能跳过第一个参数

规则 3:声明与定义分离 → 缺省值只写在声明中

工程开发中函数声明在头文件、定义在源文件,缺省值只能出现在声明里,定义不能重复写。

cpp 复制代码
// Stack.h 声明文件
typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;
// 缺省值仅在声明中指定
void STInit(ST* ps, int n = 4);

// Stack.cpp 定义文件
#include "Stack.h"
// 定义中不能再写缺省值!
void STInit(ST* ps, int n)
{
	assert(ps && n > 0);
	ps->a = (STDataType*)malloc(n * sizeof(STDataType));
	ps->top = 0;
	ps->capacity = n;
}

规则 4:缺省值只能是「常量 / 全局变量」

不能用局部变量作为缺省参数(局部变量运行时才创建,函数声明在编译期确定)。

四、缺省参数的实际应用场景

本文章采用栈初始化的案例,体现缺省参数的实用性:

  1. 不知道数据量 → 用默认值4,无需手动指定;
  2. 知道数据量很大 → 手动传参,一次性开辟空间,避免后续频繁扩容。

频繁扩容会造成的影响:
内存使用 :频繁的扩容会导致大量的内存分配和回收 ,这会降低程序的性能
停顿时间 :在数组扩容的过程中,程序可能会出现短暂的停顿时间,影响程序的效率

cpp 复制代码
// Stack.h 声明文件
typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;
void STInit(ST* ps, int n = 4);
void STPush(ST* ps, STDataType x);

// Stack.cpp 定义文件
#include "Stack.h"
void STInit(ST* ps, int n)
{
	assert(ps && n > 0);
	ps->a = (STDataType*)malloc(n * sizeof(STDataType));
	ps->top = 0;
	ps->capacity = n;
}
void STPush(ST* ps, STDataType x)
	{
		assert(ps);
		// 满了, 扩容
		if (ps->top == ps->capacity)
		{
			printf("扩容\n");
			int newcapacity = ps->capacity == 0 ? 4 : ps->capacity
				* 2;
			STDataType* tmp = (STDataType*)realloc(ps->a,
				newcapacity * sizeof(STDataType));
			if (tmp == NULL)
			{
				perror("realloc fail");
				return;
			}
			ps->a = tmp;
			ps->capacity = newcapacity;
		}
		ps->a[ps->top] = x;
		ps->top++;
	}
}

// test.cpp
#include "Stack.h"
int main()
{
	ST s1;
	STInit(&s1);         // 不传参:默认开4个空间,适合小数据

	// 知道要插入1000个数据,可以初始化就开好,避免频繁扩容
	ST s2;
	STInit(&s2, 1000);   // 传参:直接开1000空间,无扩容损耗
	for (size_t i = 0; i < 1000; i++) {
		STPush(&st2, i);	
	}
	return 0;
}

总结

本文主要针对C++的缺省参数进行解析,方便更好地理解和学习。

相关推荐
楼田莉子4 小时前
C++17新特性:optional/variant/any/string_view
c++·后端·学习
计算机安禾4 小时前
【算法分析与设计】第2篇:计算模型与渐进复杂性分析
算法
I Promise344 小时前
多传感器融合&模型后处理C++工程师面试参考回答
开发语言·c++·面试
生成论实验室4 小时前
事件、信息荷与六维态势空间——每一个事件都是一次空间的弯曲
人工智能·算法·语言模型·可信计算技术·安全架构
budingxiaomoli4 小时前
递归,搜索与回溯算法--递归
算法
风味蘑菇干4 小时前
Stream基础题目
java·算法
2501_932750264 小时前
Java反射机制基础入门
java·开发语言
KaMeidebaby4 小时前
卡梅德生物技术快报|真核蛋白表达信号肽筛选实验全流程复盘
服务器·前端·数据库·人工智能·算法
霍霍的袁4 小时前
【C++初阶】函数重载详细讲解
开发语言·c++·算法