【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++的缺省参数进行解析,方便更好地理解和学习。

相关推荐
李妍.16 小时前
02Numpy基础(上)
开发语言·python
TheBestRucy16 小时前
Python 九阳神功之贰:面向对象(下)
开发语言·python
YH552698417 小时前
GPT‑5.6 Sol 原本支持 1M 上下文,Codex 现已放开此前限制,如何看待这次调整?
java·jvm·人工智能·gpt·算法·chatgpt
吃着火锅x唱着歌17 小时前
Effective C++ 学习笔记 条款43 学习处理模板化基类内的名称
c++·笔记·学习
AI_小站17 小时前
刚面完百度的 Agent 开发岗,我才发现:世界就是个巨大的草台班子
java·开发语言·人工智能·spring·百度·langchain
felixking18 小时前
C++20 协程
开发语言·c++·协程
遥感知识服务18 小时前
从局部阈值、双极化到暗地表剔除:NASA OPERA DSWx-S1全球动态水体算法拆解
大数据·人工智能·深度学习·神经网络·算法·机器学习
晚风醉蝶18 小时前
1-13-TimSort
算法
ZJU_统一阿萨姆19 小时前
【算子开发】算子融合与Softmax_LayerNorm实现
人工智能·算法·语言模型·硬件架构
Zane19941219 小时前
CAS 与原子类:Java 如何实现无锁编程
java·开发语言