📌 相关专栏
- 【Linux专栏】
- 【C语言专栏】
- 【测试专栏】
- 【MySQL专栏】
- 【C++ 专栏】
📌 相关文章推荐
- 【测试】测试用例设计攻略(6大设计方法)
- 【C++】一文搞懂引用特性,附带顺序表完整代码实现
很高兴你点开这篇文章✨
这里会持续更新我喜欢的内容,关注我,一起慢慢变好呀
👍 点赞 ⭐ 收藏 💬 评论
文章目录
- 一、前言
- 二、缺省参数(默认参数)
- 2.1 什么是缺省参数?
- 2.2 全缺省 vs 半缺省
- 2.4 缺省参数的典型应用场景:顺序表初始化
- 三、函数重载
- 3.1 什么是函数重载?
- 3.2 编译器如何区分重载函数?
- 3.3 调用规则(匹配优先级)
- 四、总结
- 五、本文全部代码
一、前言
为什么需要缺省参数和函数重载?
🐾 在C语言中,你可能遇到过这些问题:
- 想给函数一个“默认行为”,但必须每次传参
- 想写同名的函数(比如Add支持int和double),但C不允许
C++通过缺省参数和函数重载解决了这两个痛点。
本文的代码示例的是一个顺序表(SeqList)项目,我们边看代码边学。
二、缺省参数(默认参数)
2.1 什么是缺省参数?
为缺省参数就是在声明函数时给形参一个默认值。
- 调用时如果不传参,就用默认值;
- 传参了,就用传入的值。
voidfunc(inta=0){cout<<a<<endl;}func(10);// 输出 10func();// 输出 0(缺省值)2.2 全缺省 vs 半缺省
| 类型 | 含义 | 示例 |
|---|---|---|
| 全缺省 | 所有形参都有缺省值 | void Func1(int a=10, int b=20, int c=30) |
| 半缺省 | 部分形参有缺省值 | void Func2(int b, int c=30, int a=10) |
缺省参数的规则(非常重要)
- 必须从右往左连续给出
- 正确:
void Func(int a, int b=10, int c=20) - 错误:
void Func(int a=10, int b, int c=20)
- 正确:
- 传参从左往右连续匹配,不能跳过
Func1(1,2);// a=1, b=2, c=30(缺省)Func1(1);// a=1, b=20, c=30// Func1(, 2); // 错误,不能跳过一个参数 - 半缺省函数不能“传空”
Func2(1);// 可以// Func2(); // 错误,第一个参数没有缺省值
2.4 缺省参数的典型应用场景:顺序表初始化
voidSLInit(SL*pls,intn=4);//int n=4:默认参数,指定容量为4(若调用时不传入---设新的内存容量,则自动使用4)- 如果调用
SLInit(&s, 10)→ 预分配 10 个空间 - 如果调用
SLInit(&s)→ 使用缺省值 4 个空间
好处:用户不关心容量时用默认值,关心时可以自定义。
🐶 🐾 ✨ 🐾 🐶
三、函数重载
3.1 什么是函数重载?
同一个作用域内,函数名相同,但参数列表不同(类型、个数、顺序),编译器会自动选择匹配的函数执行。
// 参数类型不同,名字都叫AddintAdd(intleft,intright);doubleAdd(doubleleft,doubleright);// 参数个数不同,名字都叫cvoidc();voidc(inta);// 参数顺序不同,名字都叫cvoidc(charb,intq);voidc(intb,charq);🐶 🐾 ✨ 🐾 🐶
3.2 编译器如何区分重载函数?
C++ 编译器会对函数名进行名字修饰(Name Mangling),把参数信息编码进函数名中。
例如:
- Add(int,int) → 可能被修饰为
_Add_int_int - Add(double,double) → 可能被修饰为
_Add_double_double
🐾 所以底层它们是不同的符号,不会冲突。
3.3 调用规则(匹配优先级)
🐾 编译器按以下顺序找匹配的函数:
- 精确匹配(参数类型完全一致)
- 隐式类型转换匹配(如 int → double)
- 报错(找不到或二义性)
Add(1,2);// 匹配 int Add(int, int)Add(1.1,2.2);// 匹配 double Add(double, double)c(10,'a');// 匹配 c(int, char)c('a',10);// 匹配 c(char, int)// c(10, 10); // ❌ 两个int,c中没有没有匹配的函数,报错🐾 编译器按以下顺序找匹配的函数:
voidc1(){}voidc1(inta=10){}c1();// ❌ 二义性错误:编译器不知道该调用哪一个四、总结
| 特性 | 核心规则 | 常见坑 |
|---|---|---|
| 缺省参数 | 从右往左连续给,传参从左往右连续匹配 | 半缺省函数不能传空、不能跳过参数 |
| 函数重载 | 同名不同参(类型/个数/顺序) | 与缺省参数混用可能产生二义性 |
这两个特性是C++相比C的重要增强,也是我们接下来学习类和构造函数的基础(构造函数本质上就是带缺省参数的特殊函数)。
🐶 🐾 ✨ 🐾 🐶
五、本文全部代码
🐾 test.cpp
#define_crt_secure_no_warnings1//缺省函数(默认参数函数),说人话就是你不给我一个新的值,我就用原来的值(缺省值—>默认值)#include<iostream>usingnamespacestd;voidfunc(inta=0)//a的缺省值是0,func是用来测试的一个函数名{cout<<a<<endl;}//全缺省----所有变量(形参)都有缺省值voidfunc1(inta=10,intb=20,intc=30)//a、b、c的缺省值分别是10、20、30{cout<<"a="<<a<<endl;cout<<"b="<<b<<endl;cout<<"c="<<c<<endl<<endl;}intmain(){//传值是从左往右连续传的,不能跳过传下一个!func1(1);//给一个实参func1();//缺省值,保持原来的值func1(1,2,3);//a=1,b=2,c=3func1(1,2);//a=1,b=2,c=30func1(1);//a=1,b=20,c=30func1();//a=10,b=20,c=30//不可以传空//func1(1, ,3);}//////////////////////////////////////////////////////////////////////////////////////////////////半缺省(部分缺省)---有些变量(形参)没有缺省值,有些有#include<iostream>usingnamespacestd;//注意:形参给缺省值(默认值)时只能从右往左给->func2(int b, int c= 30, int a = 10)// func2(int c= 30, int a = 10,int b )这个是错的voidfunc2(intb,intc=30,inta=10){cout<<"a="<<a<<endl;cout<<"b="<<b<<endl;cout<<"c="<<c<<endl<<endl;}intmain(){//传值是从左往右连续传的,不能跳过传下一个!func2(1);//给一个实参//func2();//半缺省函数不可以传空func2(1,2,3);func2(1.2);func2(1);//func2();return0;}//////////////////////////////////////////////////////////////////////////////////////////////////函数重载----同名不同参//函数重载就是“同名不同参”,即编译器根据你传的参数类型、个数、顺序,//自动帮你选最合适的那个函数去执行,输出对应函数的计算/打印结果,反之没有与之对应的就会报错#include<iostream>usingnamespacestd;//参数类型不同,名字都叫addintadd(intleft,intright){cout<<"int add(int left, int right)"<<endl;returnleft+right;}doubleadd(doubleleft,doubleright){cout<<"double add(double left,double right)"<<endl;returnleft+right;}//参数个数不同,名字都叫cvoidc(){cout<<"c()"<<endl;}voidc(inta){cout<<"c(int a)"<<endl;}//参数类型不同,名字都叫c、c1voidc(charb,intq){cout<<"c(char a,int b)"<<endl;}voidc(intb,charq){cout<<"c(int b,char a)"<<endl;}voidc1(){cout<<"c()"<<endl;}voidc1(inta=10){cout<<"c(int a)"<<endl;}intmain(){//add(1, 2) : 1 和 2 都是 int 类型,// 编译器精确匹配到 int add(int, int) ,执行 1+2=3inta1=add(1,2);cout<<a1<<endl;//add(1.1, 2.2) : 1.1 和 2.2 都是 double 类型,// 编译器精确匹配到 double add(double, double) ,执行 1.1+2.2=3.3doublea2=add(1.1,2.2);cout<<a2<<endl;c();//无参数-》匹配c()c(11);//一个int-》匹配c(int a)c(10,'a');//先int后char-》匹配c(int char)c('a',10);//先char后int-》匹配c(char int)//c(10,10); //两个int型,没有与之匹配的函数,报错return0;}🐶 🐾 ✨ 🐾 🐶
🐾 下一篇文章将讲解:
- 引用(什么是引用、引用传参、引用作为返回值)
- 顺序表的完整实现(初始化、尾插、查找、修改)
- 动态内存管理(malloc/realloc 在C++中的使用)
谢谢你看到这里呀
如果喜欢这篇内容,点个关注,下次更新不迷路✨
👍 点赞 ⭐ 收藏 💬 评论