【C++】C++核心语法:函数重载与缺省参数原理与避坑
相关专栏【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(inta0){coutaendl;}func(10);// 输出 10func();// 输出 0缺省值2.2 全缺省 vs 半缺省类型含义示例全缺省所有形参都有缺省值void Func1(int a10, int b20, int c30)半缺省部分形参有缺省值void Func2(int b, int c30, int a10)缺省参数的规则非常重要必须从右往左连续给出正确void Func(int a, int b10, int c20)错误void Func(int a10, int b, int c20)传参从左往右连续匹配不能跳过Func1(1,2);// a1, b2, c30缺省Func1(1);// a1, b20, c30// Func1(, 2); // 错误不能跳过一个参数半缺省函数不能“传空”Func2(1);// 可以// Func2(); // 错误第一个参数没有缺省值2.4 缺省参数的典型应用场景顺序表初始化voidSLInit(SL*pls,intn4);//int n4默认参数指定容量为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_intAdd(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); // ❌ 两个intc中没有没有匹配的函数报错 编译器按以下顺序找匹配的函数voidc1(){}voidc1(inta10){}c1();// ❌ 二义性错误编译器不知道该调用哪一个 结论不要同时使用缺省参数和函数重载制造二义性。四、总结特性核心规则常见坑缺省参数从右往左连续给传参从左往右连续匹配半缺省函数不能传空、不能跳过参数函数重载同名不同参类型/个数/顺序与缺省参数混用可能产生二义性这两个特性是C相比C的重要增强也是我们接下来学习类和构造函数的基础构造函数本质上就是带缺省参数的特殊函数。 ✨ 五、本文全部代码 test.cpp#define_crt_secure_no_warnings1//缺省函数(默认参数函数),说人话就是你不给我一个新的值我就用原来的值缺省值—默认值#includeiostreamusingnamespacestd;voidfunc(inta0)//a的缺省值是0,func是用来测试的一个函数名{coutaendl;}//全缺省----所有变量形参都有缺省值voidfunc1(inta10,intb20,intc30)//a、b、c的缺省值分别是10、20、30{coutaaendl;coutbbendl;coutccendlendl;}intmain(){//传值是从左往右连续传的不能跳过传下一个func1(1);//给一个实参func1();//缺省值,保持原来的值func1(1,2,3);//a1,b2,c3func1(1,2);//a1,b2,c30func1(1);//a1,b20,c30func1();//a10,b20,c30//不可以传空//func1(1, ,3);}//////////////////////////////////////////////////////////////////////////////////////////////////半缺省部分缺省---有些变量形参没有缺省值有些有#includeiostreamusingnamespacestd;//注意形参给缺省值默认值时只能从右往左给-func2(int b, int c 30, int a 10)// func2(int c 30, int a 10,int b )这个是错的voidfunc2(intb,intc30,inta10){coutaaendl;coutbbendl;coutccendlendl;}intmain(){//传值是从左往右连续传的不能跳过传下一个func2(1);//给一个实参//func2();//半缺省函数不可以传空func2(1,2,3);func2(1.2);func2(1);//func2();return0;}//////////////////////////////////////////////////////////////////////////////////////////////////函数重载----同名不同参//函数重载就是“同名不同参”即编译器根据你传的参数类型、个数、顺序//自动帮你选最合适的那个函数去执行输出对应函数的计算/打印结果反之没有与之对应的就会报错#includeiostreamusingnamespacestd;//参数类型不同名字都叫addintadd(intleft,intright){coutint add(int left, int right)endl;returnleftright;}doubleadd(doubleleft,doubleright){coutdouble add(double left,double right)endl;returnleftright;}//参数个数不同,名字都叫cvoidc(){coutc()endl;}voidc(inta){coutc(int a)endl;}//参数类型不同名字都叫c、c1voidc(charb,intq){coutc(char a,int b)endl;}voidc(intb,charq){coutc(int b,char a)endl;}voidc1(){coutc()endl;}voidc1(inta10){coutc(int a)endl;}intmain(){//add(1, 2) 1 和 2 都是 int 类型// 编译器精确匹配到 int add(int, int) 执行 123inta1add(1,2);couta1endl;//add(1.1, 2.2) 1.1 和 2.2 都是 double 类型// 编译器精确匹配到 double add(double, double) 执行 1.12.23.3doublea2add(1.1,2.2);couta2endl;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中的使用谢谢你看到这里呀如果喜欢这篇内容点个关注下次更新不迷路✨ 点赞 ⭐ 收藏 评论