【C++初阶(二)】缺省参数以及函数重载

news2024/11/17 17:44:35

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:C++初阶之路⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你学习排序知识
  🔝🔝


在这里插入图片描述

缺省参数&函数重载

  • 1. 前言
  • 2. 缺省参数
    • 2.1 全缺省
    • 2.2 半缺省
  • 3. 函数重载概念
  • 4. 几种不同类型的函数重载
  • 5. C++如何支持函数重载?
    • 5.1 C程序为什么不支持函数重载?
    • 5.2 C程序的链接过程
    • 5.3 C++函数名修饰规则
  • 6. 总结以及拓展

1. 前言

写C语言代码的时候
特别是在写数据结构时:

经常忘记传函数的参数
或者当前不需要什么参数

C++增加了缺省参数来解决这个问题

而为了解决相似功能的函数的函数名问题

C++增加了函数重载来解决这个问题

本篇文章将简单介绍缺省参数
并着重讲解函数重载的底层原理!

在这里插入图片描述


2. 缺省参数

缺省参数是声明或定义函数时
为函数的参数指定一个缺省值
在调用该函数时,
若没有指定实参
则采用该形参的缺省值
否则使用指定的实参

缺省参数分类:

  1. 全缺省
  2. 半缺省

2.1 全缺省

类似于这样的代码:

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

全缺省指的是函数的所有参数都给缺省值

有四种调用此函数的方式:

  1. 什么都不传:
Func();

此时系统默认a,b,c的值分别为
10 - 20 - 30

  1. 只传一个参数:
Func(15);

此时,a的值为15
而系统默认b,c的值为
:20-30

  1. 传两个参数:
Func(15,25);

此时a,b的值为:15 - 25
系统默认c的值为30

  1. 三个参数都传:
Func(15,25,35);

此时a,b,c的值为:15-25-35


注意: 传参不能写成这种形式:

Func(,25,);
Func(,,35);
Func(,25,35);
Func(15,,35);

2.2 半缺省

半缺省类似于这种形式:

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

只要有参数没有给缺省值
那么它就是半缺省的

注意:

  1. 半缺省参数必须从右往左依次来给出,不能间隔着给
  2. 缺省参数不能在函数声明和定义中同时出现
  3. 缺省值必须是常量或者全局变量

比如下面这样定义半缺省是不行的:

void Func1(int a=10,int b,int c);
void Func2(int a,int b=20,int c);
//有缺省值的前提是它的右边的参数都有缺省值

3. 函数重载概念

以前有一个笑话:国有两个体育项目大家根本不用看,也不用担心。一个是乒乓球,一个
是男足。前者是“谁也赢不了!”,后者是“谁也赢不了

这里使用了一语双关.
而函数重载的概念和它类似:

函数重载是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。

举个例子:

void func(int i,char ch) //函数1
{
	//...
}

void func(char ch,int i) //函数2
{
	//...
}

函数1和2可以同时存在
并且它们不是同一个函数


4. 几种不同类型的函数重载

总结三种支持函数重载的情况:

  1. 参数类型不同
int Add(int left, int right)
{
	return left + right;
}
double Add(double left, double right)
{
	return left + right;
}
  1. 参数个数不同
void f()
{
 cout << "f()" << endl;
}
void f(int a)
{
 cout << "f(int a)" << endl;
}
  1. 参数类型顺序不同
void f(int a, char b)
{
 cout << "杭州电子科技大学" << endl;
}
void f(char b, int a)
{
 cout << "圣光机联合学院" << endl;
}

(注意:下面这种不属于函数重载):

short Add(short x,short y)
{
	return x+y;
}
int Add(short x,short y)
{
	return x+y;
}

因为它们参数类型,数量,顺序都一样
只是返回值不同,不构成函数重载!


5. C++如何支持函数重载?

在C/C++中,一个程序要运行起来
需要经历以下几个阶段:

  • 预处理
  • 编译
  • 汇编
  • 链接

因为c++区别于c在这几个过程中
的差别,所以使C++能够支持函数重载


5.1 C程序为什么不支持函数重载?

定义两个源文件和一个头文件来解释:

  • func.h
  • func.c
  • main.c

在.h文件声明两个函数

int func(int x,int y);
int func(int x,double y);

这三个文件会经历以下过程:

  1. 预处理阶段

主要内容:头文件展开,宏替换
条件编译,去掉注释

这个过程结束后,func.h被展开了
main.c和func.c源文件变成了:
func.i和main.i文件

  1. 编译阶段

主要内容:语法检查和生成汇编代码

这个过程结束后,func.i和main.i
文件变成了func.s和main.s文件
(此文件中为汇编代码)

  1. 汇编阶段

主要内容:将汇编代码转换成二进制码
以便机器能够读懂

这个过程结束后,func.s和main.s
文件变成了func.o和main.o文件

注:前面的过程只用了解,真正的主角在下面!

  1. 链接过程
    func.o和main.o文件
    以及链接过程是这部分的重中之重

5.2 C程序的链接过程

func.c到func.o和main.c到main.o
都是单线程的

链接过程:

.o的目标文件会合并到一起
其次还需找一些只给了声明的函数
的函数地址

而每一个.o文件都有一个符号表
符号表中存放函数的地址

当main文件要调用这个函数时
会去符号表中找函数的地址

在这里插入图片描述

而符号表中两个func函数的地址
编译器不知道应该调用哪个
所以c程序不支持函数重载!


5.3 C++函数名修饰规则

相比起C程序而言,C++新增了一个
函数名修饰规则来支持函数重载

这个规则就是将函数的参数带入符号表
所以参数的类型,数量,顺序不同
代表的是不同的函数,找地址时就不会出错!

我们在C++的汇编代码中找到了
这两个函数对应的部分:

在这里插入图片描述

综上所述:

函数参数的类型,数量,顺序不同
那么对应在符号表中的名字就不一样
main文件再去找函数地址时就不会冲突

对比c程序:
c程序符号表中只有一个函数名
函数参数没有参与进来
所以C程序不支持相同函数名的函数


6. 总结以及拓展

前面很多过程只是为了
后面的链接.o文件打基础
所以前面的听不懂也没关系

只需要知道C++有函数名修饰规则
c++的.o文件的符号表的函数名
和函数参数相关
而c程序的符号表和参数无关!

在这里插入图片描述

拓展:
C/C++函数调用约定和名字修饰规则
有兴趣好奇的同学可以看看里面
有对vs下函数名修饰规则讲解
C/C++约定


🔎 下期预告:引用和内联函数 🔍

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/711521.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

红黑树内容及代码实现

目录 1.概念 2.性质 3.实现 3.1定义数据类型 3.2设计基本操作 3.2.1着色问题详解 3.2.2 代码基本框架 3.2.3着色问题代码 3.2.4红黑树的销毁 3.3验证基本操作 4.总结 1.概念 红黑树是一种二叉搜索树&#xff0c;但是在其中的每个结点上增加一个存储表示该节点的颜…

【数据结构】栈和队列(队列篇)

上期我们已经学习了数据结构中的栈&#xff0c;这期我们开始学习队列。 目录 1.队列的概念及结构 2.队列的实现 队列结构体定义 常用接口函数 初始化队列 队尾入队列 队头出队列 获取队列头部元素、 获取队列队尾元素 获取队列中有效元素个数 检测队列是否为空 销毁…

chatgpt赋能python:用Python轻松给手机用户发送短信——优秀的工具在手,无限可能!

用Python轻松给手机用户发送短信——优秀的工具在手&#xff0c;无限可能&#xff01; 作为一个有10年Python编程经验的工程师&#xff0c;我想分享一下如何用Python给手机用户发送短信。Python是目前非常流行的编程语言之一&#xff0c;它可以轻松地完成很多任务。而给用户发…

13.定时器中断

1.通用定时器工作过程&#xff1a; 2.时钟选择&#xff1a; 内部时钟(CK_INT);外部时钟模式1&#xff1a;外部输入脚(TIx)&#xff1b;外部时钟模式2&#xff1a;外部触发输入(ETR)&#xff1b;内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器&#xff0c;例如可…

【Kafka面试题1】Kafka消费者是pull(拉)还是push(推)模式,这种模式有什么好处?

Kafka消费者是pull(拉)还是push(推)模式&#xff0c;这种模式有什么好处&#xff1f; 一、概述回答 Kafka中的Producer和consumer采用的是push-and-pull模式&#xff0c;即Producer只管向broker push消息&#xff0c;consumer只管从broker pull消息&#xff0c;两者对消息的生…

从零用自己数据跑R3LIVE

1、相机内参标定 相机选用4mm的广角相机&#xff0c;相机内参标定选择用最常见的棋盘格方法&#xff0c;首先安装ROS自带的包 sudo apt install ros-melodic-camera-calibration 用usb_cam启动相机后进行标定 。 rosrun camera_calibration cameracalibrator.py --size 8x6…

【Linux】网络编程相关概念介绍、UDP套接字简单演示、最简单的UDP公共聊天室实现~

文章目录 [toc] 网络编程 - 套接字一些概念1. 源ip地址与目的ip地址2. 端口号 和 socket套接字 **问题 3. 源端口号和目的端口号4. 认识TCP协议基本特点5. 认识UDP协议基本特点6. 网络字节序 socket编程接口**struct sockaddr**接口演示: 简单的UDP网络通信int socket()UDP网络…

读书笔记-《ON JAVA 中文版》-摘要18[第十八章 字符串-1]

文章目录 第十八章 字符串1. 字符串的不可变2. 的重载与 StringBuilder3. 意外递归4. 字符串操作5. 格式化输出5.1 printf()5.2 System.out.format()5.3 Formatter 类5.3.1 格式化修饰符5.3.2 Formatter 转换 5.4 String.format() 6. 自我学习总结 第十八章 字符串 字符串操作…

【专题速递】更多的解决方案:传统行业不再「传统」

// 音视频技术作为企业数字化转型的关键技术与能力之一&#xff0c;为众多传统行业在生产、服务、管理与维护等方面提供了强有力的支持。那么&#xff0c;音视频技术是如何助力企业数字化转型的&#xff1f;7月28日LiveVideoStackCon上海站数字化与行业案例专场&#xff0c;为…

【AI】PyTorch安装记录及Anaconda环境配置

【AI】PyTorch安装记录及Anaconda环境配置 说下本地环境&#xff0c;RTX4070 12GB GPU&#xff1b;618刚买&#xff0c;不能让他闲着&#xff0c;配置一下炼丹环境&#xff0c;开始为打工人工作。为了方便后续部署模型之间依赖不冲突&#xff0c;所以使用Anaconda管理Python环…

【数据结构】第 1~10 章:思维导图与重点汇总

目录 一、概论 &#xff08;1&#xff09;思维导图 &#xff08;2&#xff09;常见名词 &#xff08;3&#xff09;数据结构的定义 &#xff08;4&#xff09;抽象数据类型 ADT &#xff08;5&#xff09;算法 &#xff08;6&#xff09;评价算法的好坏的因素 &am…

Python基础 —— 循环语句

如约来更新循环语句了.说到循环&#xff0c;有一定编程基础的小伙伴们都知道&#xff0c;我们最常用的循环莫过于 while循环&#xff0c;for循环和goto循环&#xff08;不过goto也不怎么常用&#xff09;&#xff0c;所以今天就来说一说 while循环和 for循环 来看一下本文大致…

IMX6ULL系统移植篇-uboot基础命令

一. uboot 启动 当设备上电启动时&#xff0c;需要马上按下回车键&#xff0c;开发板启动会停止在 uboot的启动Log信息时刻。 这就是 uboot的命令模式&#xff0c;即可以输入 uboot命令进行一些操作。 二. uboot 基础命令 1. help 命令 当开发板上电启动后&#xff0c;马…

电脑如何设置外网内网一起使用

如果你的电脑支持连接无线网&#xff0c;就可以设置内网外网一起使用。一般情况下&#xff0c;连接无线网还是网线都是系统自动链接的,但有时候开发中需要内网外网一块使用&#xff0c;不用手动切换网络。 首先确保我们的电脑有双网卡&#xff0c;可以两个都是有线网卡&#xf…

【机械臂视觉抓取从理论到实战】

1. 概述 GR-CNN&#xff1a;https://paperswithcode.com/paper/antipodal-robotic-grasping-using-generative 2. 环境搭建及模型训练 GR-CNN&#xff1a;https://github.com/skumra/robotic-grasping 下载源码创建环境 #下载robotic-grasping源码 git clone https://github.…

CVE-2021-3493:Overlay 文件系统 Ubuntu 本地提权漏洞分析

分析此漏洞的文章非常多&#xff0c;在此只是记录一下复现漏洞的过程以及对漏洞的个人理解。Linux 内核漏洞有一定的准入门槛&#xff0c;不适合小白阅读。 基本信息 [影响范围] Ubuntu 14.04 ~20.10 [漏洞描述] Ubuntu 内核代码允许低权限用户在使用 unshare() 函数创建的…

李彦宏:AI原生应用比大模型数量更重要

6月26日&#xff0c;百度创始人、董事长兼首席执行官李彦宏出席“世界互联网大会数字文明尼山对话”&#xff0c;发表了题为 《大模型重塑数字世界》 的演讲。 大模型是当下全球科技创新的焦点&#xff0c;也是全球人工智能竞赛的主战场。李彦宏认为&#xff0c;“新的国际竞争…

箱线图概念和使用介绍

箱线图时一种针对连续型变量的统计图。通常用作比较。 箱子中间的一条线&#xff0c;是数据的中位数&#xff0c;代表了数据的平均水平。 箱子的上限和下限&#xff0c;分别是数据的上四分位数和下四分位数&#xff0c;意味着箱子包含50%的数据。因此&#xff0c;箱子的高度在…

23.RocketMQ之NameServer处理Broker心跳包,更新本地路由信息

NameServer处理Broker心跳包,更新本地路由信息 DefaultRequestProcessor继承自NettyRequestProcessor:处理各种客户端的请求&#xff0c;如果请求类型是为REGISTER_BROKER&#xff0c;则将请求转发到RouteInfoManager#regiesterBroker,主要是服务器端 或者客户端或者broker发送…

go语言环境安装

文章目录 环境介绍安装软件包步骤环境变量设置来一个经典的hello worldNice 最近的项目需要用到go来开发了&#xff0c;前几天就已经在看书了&#xff0c;今天是个周末&#xff0c;先在家里的机器上把环境搭好&#xff0c;特此记录一下。 环境介绍 下载地址&#xff1a;https:…