【C++入门】缺省参数、函数重载与引用

news2025/1/24 17:59:18

💞💞 前言

hello hello~ ,这里是大耳朵土土垚~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹
在这里插入图片描述

💥个人主页:大耳朵土土垚的博客
💥 所属专栏:C++入门至进阶
从今天开始土土将会不定期更新有关C++的内容,希望大家多多点赞关注💖💖

目录

  • 💞💞 前言
  • 1. 缺省参数
    • 1.1 缺省参数概念
    • 1.2 缺省参数分类
  • 2.函数重载
    • 2.1函数重载概念
    • 2.2函数重载原因
  • 3.引用
    • 3.1引用概念
    • 3.2引用特性
    • 3.2常引用
    • 3.3使用场景
    • 3.4引用和指针的区别
  • 4.结语

1. 缺省参数

1.1 缺省参数概念

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

#include<iostream>
using namespace std;//使用using namespace 命名空间名称引入C++标准
void Func(int a = 0)
 {
 	cout<<a<<endl;
 }
 int main()
 {
	Func();     // 没有传参时,使用参数的默认值 
	Func(10);   // 传参时,使用指定的实参
	return 0;
 }

结果如下:
在这里插入图片描述

可以看到在定义void Func(int a = 0)时给int a 参数赋值为0;
所以当使用该函数时,如果不传参数:Func(); 就默认传的参数为之前定义时赋值的0;
如果传参数:Func(10); 就正常传参即可;

注意:

  • 缺省参数不能在函数声明和定义中同时出现(写在声明中):
 //a.h
  void Func(int a = 10);
  
  // a.cpp
  void Func(int a = 20)
  {}
  
  // 注意:如果声明与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该用那个缺省值。
  • 缺省值必须是常量或者全局变量;
  • C语言不支持(编译器不支持)缺省参数;

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;
 }

半缺省参数就是指定义函数时将部分的参数赋值;
注意:半缺省参数必须从右往左依次连续来给出,中间不能有间隔;

2.函数重载

2.1函数重载概念

  • 函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数或类型或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。
  • 函数重载的优点是能够提高代码的可读性和可维护性。通过使用同一个函数名来表示一组相关的操作,可以让调用者更容易理解代码的意图,并且减少了代码的重复性。
  • 函数重载的条件是函数名相同,但是参数列表不同。参数列表可以包括参数的个数、类型、顺序等方面的差异。在编译器中,通过函数的参数列表来区分同名的函数,并选择合适的函数进行调用。

例如:

#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{
    cout << "int Add(int left, int right)" << endl;
    return left + right;
}
double Add(double left, double right)
{
    cout << "double Add(double left, double right)" << endl;
    return left + right;
}


// 2、参数个数不同
void f()
{
    cout << "f()" << endl;
}
void f(int a)
{
    cout << "f(int 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);
    Add(10.1, 20.2);
    f();
    f(10);
    f(10, 'a');
    f('a', 10);
    return 0;
}

结果如下:
在这里插入图片描述

可以看到虽然函数名相同,但是对应不同的参数会调用不同的函数

  • 这里注意,相同类型的参数顺序调换不构成函数重载:
int Add(int left, int right)
{
    cout << "int Add(int left, int right)" << endl;
    return left + right;
}
int Add(int right, int left)
{
    cout << "int Add(int left, int right)" << endl;
    return left + right;
}

结果如下:
在这里插入图片描述

  • 当然如果两个函数函数名和参数是一样的,返回值不同是不构成重载的,因为调用时编译器没办法区分。

2.2函数重载原因

  • C语言不支持函数重载的主要原因是它的编译器在进行函数调用时是根据函数名来确定具体调用的函数的,在编译阶段就已经决定了函数的调用方式。而函数重载是指多个函数拥有相同的名称但具有不同的参数列表,编译器无法根据函数名来确定具体调用的函数。因此,C语言无法实现函数重载功能。

  • 而C++是通过函数修饰规则来区分同名的函数,只要参数不同,修饰出来的名字就不一样,就支持了重载。

3.引用

3.1引用概念

  • 引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间
  • 它允许我们使用一个变量名来引用另一个变量的值,而不是创建一个新的变量
  • 引用通常用于传递函数的参数、返回函数值和简化语法

在C++中,我们可以通过以下方式定义一个引用:

type &ref = variable;//类型&  引用变量名(对象名) = 被引用实体

例如:

void TestRef()
 {
 	 int a = 10;
	 int& ra = a;//<====定义引用类型
	 printf("%p\n", &a);
	 printf("%p\n", &ra);
 }

注意:引用类型必须和引用实体是同种类型的

在这里插入图片描述
再举个例子:

可以看到它们都是同一个地址,指向同一个变量

#include <iostream>

int main() {
    int num = 10;
    int &ref = num; // 引用num变量

    std::cout << "num: " << num << std::endl;
    std::cout << "ref: " << ref << std::endl;

    num = 20;
    std::cout << "num: " << num << std::endl;
    std::cout << "ref: " << ref << std::endl;

    ref = 30;
    std::cout << "num: " << num << std::endl;
    std::cout << "ref: " << ref << std::endl;

    return 0;
}
 

结果如下:

num: 10
ref: 10
num: 20
ref: 20
num: 30
ref: 30

可以看到,无论我们通过num还是ref来修改变量的值,都会影响到另一个变量的值,因为它们实际上是同一个变量的不同名称。

3.2引用特性

  • 引用在定义时必须初始化
  • 一个变量可以有多个引用
  • 引用一旦引用一个实体,再不能引用其他实体
void TestRef()
 {
	int a = 10;
    // int& ra;   // 该条语句编译时会出错
	int& ra = a;
	int& rra = a;
	printf("%p  %p  %p\n", &a, &ra, &rra);  
}

结果如下:
在这里插入图片描述

3.2常引用

C++中的常引用有两种情况:

  1. const引用:使用const关键字来修饰引用,表示引用的值不可修改。例如:
int x = 10;
const int& ref = x;

在上面的例子中,ref是一个对x的常引用,意味着不能通过ref来修改x的值。

  1. 常对象的引用:当引用一个常对象时,引用也必须是常引用。例如:
const int x = 10;
const int& ref = x;

在上面的例子中,ref是对常对象x的常引用。

常引用的作用是为了在不修改值的情况下使用对象,同时可以避免不必要的复制。常引用经常用于函数参数中,以便避免对实参进行复制。

指针和引用进行赋值和初始化时,权限可以缩小,但是不能放大

例如:

const int x = 10;
int& ref = x;//这是错误的,它放大了权限

在上面的例子中,原本的x被const修饰不能被改变数据,但是ref引用它时没有用const修饰说明可以被改动,放大了权限是不被接受的;这和指针是类似的:const int* p1 = NULL; int* p2 = p1;//这也是错误的

3.3使用场景

  • 做参数
void Swap(int& left, int& right)
 {
 int temp = left;
 left = right;
 right = temp;
 }

结果如下:
在这里插入图片描述

可以看到我们没有使用传递变量的指针给函数就改变了实参的数据;

使用引用作为函数参数可以避免复制大量的数据,提高函数的效率。同时,通过引用传递参数可以实现对原始数据的修改,而不需要借助指针来实现。

  • 做返回值

引用作为函数的返回值前提是:返回的值在调用完函数后不会被释放销毁

例如:

int& Count()
 {
 static int n = 0;
 n++;
 return n;
 }

n用static修饰为静态全局变量即使函数调用结束也不会被释放,所以可以用引用作为函数的返回值,这样就不需要再临时拷贝一份,减少了空间的消耗;


那么作为函数的返回值有什么作用呢?
举个例子:

#include<iostream>
#include<assert.h>
#define N 10
using namespace std;
//顺序表
typedef struct AY
{
	int arr[N];
	int size;
}AY;
int& PosAt(AY& ay, int x)
{
	assert(x < N);
	return ay.arr[x];
}
int main()
{
	AY ay;
	for (int i = 0; i < N; i++)
	{
		PosAt(ay, i) = i;//利用引用返回修改对应的值
	}
	for (int i = 0; i < N; i++)//打印
	{
		cout << PosAt(ay, i) << " ";
	}
	cout << endl;
	return 0;
}

结果如下:
在这里插入图片描述

从上面的函数我们可以知道引用返回除了可以减少拷贝还可以修改返回的对象;

总结:如果函数返回时,出了函数作用域,如果返回对象还在(还没还给系统),则可以使用引用返回,如果已经还给系统了,则必须使用传值返回。

3.4引用和指针的区别

(1)在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间;而指针是保存着变量的地址的,是有独立的空间的;

例如:

int main()
 {
 int a = 10;
 int& ra = a;
 cout<<"&a = "<<&a<<endl;
 cout<<"&ra = "<<&ra<<endl;
 return 0;
 }

结果如下:
在这里插入图片描述

通过上述例子我们发现引用和原来的变量的地址是一样的;

(2)在底层实现上实际是有空间的,因为引用是按照指针方式来实现的;

例如:

#include<iostream>
using namespace std;
int main()
{
	int a = 10;
	int& ra = a;
	ra = 20;
	int* pa = &a;
	*pa = 20;
	return 0;
}

结果如下:
在这里插入图片描述

通过上述例子,我们调试查看反汇编,发现引用和指针操作底层逻辑是一样的;

(3)引用和指针的不同:

  • 引用概念上定义一个变量的别名,指针存储一个变量地址;
  • 引用在定义时必须初始化,指针没有要求;
  • 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体;
  • 没有NULL引用,但有NULL指针;
  • 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节);
  • 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小;
  • 有多级指针,但是没有多级引用;
  • 访问实体方式不同,指针需要显式解引用,引用编译器自己处理;
  • 引用比指针使用起来相对更安全;

4.结语

以上就是C++中缺省参数、函数重载以及引用的所有内容啦 ~,缺省参数函数重载以及引用的出现是为了补充C语言语法的不足以及对C语言设计不合理的地方进行优化,引用的出现大大降低了我们学习C语言时相对于指针的难度,也便于我们更好的理解和使用,完结撒花 ~🥳🥳🎉🎉🎉

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

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

相关文章

Severt和tomcat的使用(补充)

打包程序 在pom.xml中添加上述代码之后打包时会生成war包并且包的名称是test 默认情况打的是jar包.jar里量但是tomcat要求的是war包. war包Tomcat专属的压缩包. war里面不光有.class还有一些tomcat要求的配置文件(web.xml等)还有前端的一些代码(html, css, js) 点击其右边的m…

WPS二次开发系列:WPS SDK实现文档打印功能

在办公场景或者家教场景中经常碰到需要对文档进行打印的能力&#xff0c;今天给大家带来一篇如何通过WPS SDK调用WPS打印接口实现文档打印能力 最终实现效果图 实现步骤 2.1. 申请集成资料 通过向WPS官方发送邮件申请&#xff0c;审批通过后即可获取集成相关资料&#xff0c;详…

数据备份的演变:数字时代的一个关键方面

微信关注获取更多内容 数据备份至关重要&#xff0c;涵盖了其过去、现在和未来&#xff0c;是数字时代任何企业运营的一个重要方面。 如今&#xff0c;公司运营的几乎每个方面&#xff0c;从客户信息到内部财务数据&#xff0c;都以数字方式存储。 有鉴于此&#xff0c;数据…

视频压缩软件都有哪些?分享4款专业的视频软件!

在数字化时代&#xff0c;视频已经成为我们生活中不可或缺的一部分。然而&#xff0c;随着视频质量的不断提升&#xff0c;其占用的存储空间也在迅速增长。为了解决这个问题&#xff0c;视频压缩软件应运而生。本文将为您介绍几款热门的视频压缩软件&#xff0c;帮助您选择最适…

后端nginx使用set_real_ip_from获取用户真实IP

随着nginx的迅速崛起&#xff0c;越来越多公司将apache更换成nginx. 同时也越来越多人使用nginx作为负载均衡, 并且代理前面可能还加上了CDN加速&#xff0c;但是随之也遇到一个问题&#xff1a;nginx如何获取用户的真实IP地址. 前言&#xff1a;Nginx ngx_http_realip_module…

JVM—对象的创建流程与内存分配

JVM—对象的创建流程与内存分配 创建流程 对象创建的流程图如下&#xff1a; 对象的内存分配方式 内存分配的方式有两种&#xff1a; 指针碰撞&#xff08;Bump the Pointer&#xff09;空闲列表&#xff08;Free List&#xff09; 分配方式说明收集器指针碰撞&#xff08…

flutter升级3.10.6Xcode构建报错

flutter sdk 升级Xcode报错收集&#xff0c;错误信息如下&#xff1a; Error (Xcode): Cycle inside Runner; building could produce unreliable results.没问题版本信息&#xff1a; Xcode&#xff1a;15.3 flutter sdk &#xff1a;3.7.12 dart sdk&#xff1a;2.19.6 …

hadoop分布式计算组件

什么是计算、分布式计算&#xff1f; 计算&#xff1a;对数据进行处理&#xff0c;使用统计分析等手段得到需要的结果 分布式计算&#xff1a;多台服务器协同工作&#xff0c;共同完成一个计算任务 分布式计算常见的2种工作模式 分散->汇总(MapReduce就是这种模式)中心调…

《价值》-张磊-高瓴资本-5-投资是一场修行;坚持第一性原理;避开陷阱;信誉就是生命

第五章&#xff1a;价值投资者的自我修养 价值投资不是投资者之间的零和游戏&#xff0c;而是共同把蛋糕做大的正和游戏。 从事投资的过程中&#xff0c;我渐渐发觉&#xff0c;投资 一方面是对真理的探寻&#xff0c;探索外部世界&#xff1b;另一方面是谋求心灵的宁静&#x…

Java: LinkedList的模拟实现

一、双向链表简介 上一篇文章我介绍了单向链表的实现&#xff0c;单向链表的特点是&#xff1a;可以根据上一个节点访问下一个节点&#xff01;但是&#xff0c;它有个缺点&#xff0c;无法通过下一个节点访问上一个节点&#xff01;这也是它称为单向链表的原因。 那么&#x…

K8S - Service简介和 1个简单NodePort例子

大纲图 流量方向 如上图&#xff0c; 当用户or 别的service 从k8s 集群外部访问 集群内的services 流量方向有两种 一种是垂直方向&#xff0c; 通过域名 -> Load Balancer -> gateway -> services , 在k8s 一般是通过ingress 来实现&#xff0c; 而ingress 不是本文…

免费https详细教程

简单叙述一下https的定义和实现https的一些基本作用&#xff0c;然后会给到申请SSL证书的方式以及安装部署流程&#xff0c;最终实现网站的https访问。 随着互联网的快速发展&#xff0c;网络安全问题日益凸显。在互联网上传输敏感信息、进行在线交易和共享个人数据时&#xf…

万界星空科技生产工时管理系统

生产工时管理系统是一个管理系统&#xff0c;生产管理人员可以详细地、逐项活动地查看生产和即时劳动力数据&#xff0c;特别是活动级劳动力信息&#xff0c;辅助生产管理人员利用从车间获得的效率数据&#xff0c;实时监控生产流程&#xff0c;并在提高生产率&#xff0c;控制…

TLF9471 V33 WK/ VSENSE

1 WK/VSENSE 输入框图 TLF9471实现以下唤醒源: Static Sense:WK/VSENSE输入和/或GPIO WK输入作为尾流源永久激活,即WK/VSENSE输入和/或GPIO WK输入作为尾流源永久激活。Cyclic Sense:WK/VSENSE输入仅在循环感知周期的开启时间内激活。内部定时器在接通时激活GPIO HS,用于感…

C语言开发实战:使用EasyX在Visual Studio 2022中创建井字棋游戏

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

CVE-2024-3148 DedeCms makehtml_archives_action sql注入漏洞分析

DedeCMS&#xff08;也称为织梦CMS&#xff09;是一款基于PHPMySQL的开源内容管理系统。 在 DedeCMS 5.7.112 中发现一个被归类为严重的漏洞。此漏洞会影响某些未知文件dede/makehtml_archives_action.php的处理。操作导致 sql 注入。攻击可能是远程发起的。该漏洞已向公众披露…

Word wrap在计算机代表的含义(自动换行)

“Word wrap”是一个计算机术语&#xff0c;用于描述文本处理器在内容超过容器边界时自动将超出部分转移到下一行的功能。在多种编程语言和文本编辑工具中&#xff0c;都有实现这一功能的函数或选项。 在编程中&#xff0c;例如某些编程语言中的wordwrap函数&#xff0c;能够按…

pdf、docx、markdown、txt提取文档内容,可以应用于rag文档解析

返回的是文档解析分段内容组成的列表&#xff0c;分段内容默认chunk_size: int 250, chunk_overlap: int 50&#xff0c;250字分段&#xff0c;50分段处保留后面一段的前50字拼接即窗口包含下下一段前面50个字划分 from typing import Union, Listimport jieba import recla…

鸿蒙ArkTS开始实例:【canvas实现签名板功能】

使用ArkTS中的canvas实现签名板的功能&#xff0c;canvas画布大家都很熟悉&#xff0c;我们会用它经常实现一些画板或者图表、表格之类的功能。canvas签名板是我在开发APP过程中实现的一个功能&#xff0c;开发过程中也是遇到比较多的问题。我会按照以下几点来讲解开发整个过程…

npm版本切换工具nvm

有了nvm&#xff0c;可以在一台机器上同时安装多个版本的nodejs&#xff0c;然后指定使用某个版本。 前端开发的时候&#xff0c;安装依赖一直是个令我头痛的问题。总是报错&#xff0c;或者不是少了这样就是少了那样&#xff0c;鸡飞狗走。以往&#xff0c;一般要装个enpm&am…