【C++】巧用缺省参数与函数重载:提升编程效率的秘密武器

server/2024/10/21 19:53:25/

在这里插入图片描述

C++语法相关知识点可以通过点击以下链接进行学习一起加油!
命名空间

本章将分享缺省参数与函数重载相关知识,为了更加深入学习C++打下了坚实的基础。本章重点在于缺省参数与函数重载使用前提与注意事项

请添加图片描述
Alt

🌈个人主页:是店小二呀
🌈C语言笔记专栏:C语言笔记
🌈C++笔记专栏: C++笔记
🌈初阶数据结构笔记专栏: 初阶数据结构笔记
🌈Linux笔记专栏: Linux笔记

🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅
请添加图片描述

文章目录

  • 一、缺省参数
    • 1.1 缺省参数的概念
    • 1.2 缺省函数分类
    • 1.3 正确使用缺省参数前提
  • 二、函数重载
    • 2.1 函数重载概念
    • 2.2 使用函数重载前提
    • 2.3 C++支持函数重载的原理-名字修饰(name Mangling)

一、缺省参数

1.1 缺省参数的概念

缺省参数是声明或定义函数时为函数的参数指定一个缺省值(默认值)。在调用该函数时,如果没有指定实参,则采用该形参的缺省值(默认值),否则使用指定的实参。

#include <iostream>
using namespace str;
void Func(int a=0)
{count<<a<<endl
}
int main()
{Func();//0Func(10);//10
}
1.没有传参,使用参数的默认值
2.传参,使用指定的参数

1.2 缺省函数分类

全缺省函数:

void Func(int a = 10, int b = 20, int c = 30)
{cout<<"a = "<<a<<endl;cout<<"b = "<<b<<endl;cout<<"c = "<<c<<endl;
}

半缺省函数:

void Func(int a, int b = 10, int c = 20)
{cout<<"a = "<<a<<endl;cout<<"b = "<<b<<endl;cout<<"c = "<<c<<endl;
}

1.3 正确使用缺省参数前提

第一点重点):

  1. 缺省参数不能在函数声明和定义同时出现

说明:从两个方面来说,一方面如果声明与定义位置同时出现,恰好两个位置提供的值不同,那么编译器就无法确定到底该使用哪个缺省值,另一个方面来说就算两个位置提供的值相同,祖师爷规定也不能这种方式操作

​ 2.缺省参数选择在函数声明出现

说明:一般将声明放在头文件中,而头文件将在编译阶段进行展开进行语法检查。对于函数地址而言是用于执行一堆指令(Call 函数中指令)到CPU中处理,那么函数地址是第一个指令地址,而函数定义才会使用到地址,函数声明不存在有效地址。

那么在编译阶段,对于函数声明编译器选择放过呢?由于编译器是进行语法分析,在链接时,函数声明会通过无效地址到符号表定位到真正函数的地址。

重定位就是在链接地址跟运行地址不同的情况下,执行一段位置无关码,这段位置无关码的作用就是将原来的那份代码全部复制到链接地址那里去,然后自己再长跳转到新的那份代码的刚刚执行的那个位置。这样就实现了链接地址跟运行地址一致的情况

请添加图片描述

具体场景辅助理解:
你要买房需要首付30w,现在手头只有20w,打了一通你的室友电话,你的室友同意借你10w。到首付的时候,你室友的10w迟迟没有到账,后面才知道你室友家破产了,借不出去答应借你10w(声明/承诺)

  • 答应借你10w(声明/承诺)
  • 转账给你10w(定义/兑现)

第二点:

  • 半缺省实(或形)参数必须从右往左依次来给出,不允许间隔着给

说明:在语法层次上,我们属于学习者是根据语法规定来进行学习。如果想要更有说服力的答案,在调试阶段,通过鼠标右边点击反汇编,从图中我们可以得到传参是传参是从右到左push数据

请添加图片描述

部分补充:

  • 缺省参数必须是常量或者全局变量
  • C语言不支持缺省参数

缺省参数使用场景:无法得知插入准确值

//1.确定要插入100个数据
StackInit(&st1, 100);
//1.确定要插入10个数据
StackInit(&st2, 10);
// 3、不知道要插入多少个
StackInit(&st3);

二、函数重载

自然语言中,一个词可以有多重含义,人们可以通过上下文来判断词真实的含义,该词被重载了。(有卧龙必有凤雏)

2.1 函数重载概念

函数重载是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,常用来处理实现功能类似数据类型不同的问题,而C语言不允许同名函数

2.2 使用函数重载前提

函数重载需要满足其中一个条件:

  1. 参数类型不同
  2. 参数个数不同
  3. 参数类型顺序不同(本质是参数类型不同)
#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int x,int y)
{return x+y;
}
int Add(double x,double y)
{return x+y;
}// 2、参数个数不同
void f()
{cout<<"f()"<<endl;
}
void f(int a)
{cout<<"f(a)"<<endl;
}// 3、参数类型顺序不同(本质还是参数类型不同)
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}
int main()
{Add(10, 20); //call(?)Add(10.1, 20.2); //call(?)f();f(10);f(10, 'a');f('a', 10);return 0;
}

2.3 C++支持函数重载的原理-名字修饰(name Mangling)

我们知道C语言不支持函数重载,那么C++如何去支持函数重载呢?

    f(10, 'a');  //call(?)f('a', 10);  //call(?)

首先简单快速过一遍,关于程序在编译环境下的流程

在C/C++,程序运行之前,需要进行以下几个阶段:预处理、编译、汇编、链接

请添加图片描述

每个编译器都有属于自己的一套函数名修饰规则,windows下vs的修饰规则过于复杂,而Linux下g++的修饰规则简单

int Add(int a,int b)
{return a+b;
}
void func(int a,double b,int *p)
{}
int main()
{Add(1,2);func(120);return0
}

采用C语言编译器

请添加图片描述

采用C++编译器
请添加图片描述

  • C语言在linux下,采用gcc编译完成后,函数名字的修饰没有发生改变
  • C++在linux下,采用gcc编译完成后,函数名字的修饰发生改变,编译器将函数参数类型信息添加到修饰后名字中

梳理:由于C语言在链接时,直接使用函数名去找地址,同名函数无法区分不开。C++可以通过函数名修饰规则,将名字引入参数类型(不同编译器有不同规则)。只要参数不同,修饰出来的名字就不一样,就支持了重载。(如果两个函数的函数名和参数时一样的,返回值不同是不构成重载的)


以上就是本篇文章的所有内容,在此感谢大家的观看!这里是店小二呀C++笔记,希望对你在学习C++语言旅途中有所帮助!
请添加图片描述


http://www.ppmy.cn/server/93532.html

相关文章

程序员纯粹八股文的危害有哪些,应该如何来解决?

“八股文”这个词在程序员面试的上下文中通常指的是那些被广泛讨论、反复练习的问题和答案&#xff0c;它们往往围绕着一些经典的技术知识点&#xff0c;例如算法、数据结构、设计模式等。这些知识在面试中被频繁提及&#xff0c;以至于应聘者经常会提前准备并背诵这些答案&…

隧道可视化:实时监控保障行车安全

通过图扑可视化实现隧道的实时监控、数据分析及智能报警系统&#xff0c;提供全面的隧道管理和决策支持&#xff0c;提升行车安全&#xff0c;优化维护策略&#xff0c;确保交通顺畅。

如何保证前后端交互信息不被篡改。

先说说前后端有哪些认证方式来保证&#xff1a; 基于 session 的认证方式&#xff1a;前端在用户登录成功后&#xff0c;后端会在服务器端生成一个唯一的 session ID&#xff0c;并将该 session ID 返回给前端&#xff0c;在后续的请求中&#xff0c;前端需要带上该 session ID…

C语言第九天笔记

数组的概念 什 么是数组 数组是 相同类型&#xff0c; 有序数据的集合。 数 组的特征 数组中的数据被称为数组的 元素&#xff0c;是同构的 数组中的元素存放在内存空间里 (char player_name[6]&#xff1a;申请在内存中开辟6块连续的基于char类 型的变量空间) 衍生概念&…

【c++】多线程

多线程可以解决什么问题&#xff0c;最重要的用途是什么&#xff1f; 多线程技术在现代软件开发中扮演着至关重要的角色&#xff0c;它可以解决多种问题并带来显著的好处。以下是多线程最重要的几个用途&#xff1a; 资源利用最大化: 多线程可以充分利用多核处理器的能力&…

实验21.实现 printf

已完成实验 已完成实验链接 简介 实验 21. 实现 printf 总结 简化系统调用和中断&#xff0c;用 eax 代表调用号参数&#xff0c;ebx,ecx,edx 来代表参数(syscall.c kernel.s) 添加 write 的系统调用接口(syscall.c, syscall-init.c, print.s) 注意&#xff1a;要更改 p…

注册中心--Eureka

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;个人专栏&#xff1a;Spring Cloud实战&#x1f4d5;格言&#xff1a;吾愚多不敏&#xff0c;而愿加学欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 1.项目问题 2.解决URL问题 2.1解决思路 2.2注册中心 2.3 CAP理…

【个人亲试最新】WSL2中的Ubuntu 22.04安装Docker

文章目录 Wsl2中的Ubuntu22.04安装Docker报错解决完全卸载Docker参考博客 &#x1f60a;点此到文末惊喜↩︎ Wsl2中的Ubuntu22.04安装Docker 友情提示&#xff1a;确定为wsl2ubuntu22.04&#xff0c;若按照以下步骤失败&#xff0c;请完全卸载后重装docker&#xff0c;并检查ws…