C++入门学习(2)

news2024/12/22 19:45:41

思维导图:

一,缺省参数

如何理解缺省参数呢?简单来说,缺省参数就是一个会找备胎的参数!为什么这样子说呢?来看一个缺省参数就知道了!代码如下:

#include<iostream>
using  std::cout;
using std::endl;
int Add(int a = 70, int b = 5)
{
	return a + b;
}

int main()
{
	int ret1 = Add();
	int ret2 = Add(100, 80);

	cout <<"ret1:" << ret1 << endl;
	cout <<"ret2:" << ret2 << endl;
}

这个程序打印的结果是什么呢?通过程序运行可以看到打印的结果是:

ret1:75
ret2:180

通过这个程序的运行你大概知道缺省参数是个什么东西了吧!再来一个代码:

#include<iostream>
using  std::cout;
using std::endl;
void Print(int a = 5, int b = 6, int c = 7)
{
	cout << a << " ";
	cout << b << " ";
	cout << c << endl;
}
int main()
{
	Print();
	Print(9);
	Print(8, 8);
	Print(6, 6, 6);
	return 0;
}

 这段代码打印的结果是什么呢?程序运行打印结果如下:

5 6 7
9 6 7
8 8 7
6 6 6

可以看到当我们在调用Print这个函数时如果在外面传入值的话,在Print函数运行时就会使用外面传入的值。如果外面没有传入值的话就会使用函数参数被赋予的值。这个被赋予的值就是缺省值!所以对应的参数就被叫做缺省参数缺省参数分为全缺省和半缺省!半缺省不是缺省一半而是缺省部分参数。

使用缺省参数时要注意的点

 1.在外面传入数值时要从左往右传。假如跳着传就会报错。

  如对第二个函数Print,如果这样传参就会报错:

Print(,9,);//跳过第一个传参直接传给第二个参数

 2.缺省参数要从右往左缺省。

  如对第二个函数Print的缺省值调整成下面的样子就会报错:

void Print(int a = , int b = 6, int c = 7)

 3.声明和定义中不能都给缺省值,要给最好在声明中给。

缺省参数的作用

上面说了一大堆关于缺省参数的东西,那这个缺省参数究竟有什么作用呢?下面我们来回顾一个叫做顺序表的东西。为了将顺序表的空间开辟出来,我们大概需要经历三步: 

typedef  struct List
{
	int *a;
	int size;
	int capacity;
}List;

void ListInit(List* pList)
{
	pList->a = NULL;
	pList->size = 0;
	pList->capacity = 0;
}
void PushBack(List* pList)
{
	//检查是否为NULL,malloc空间
	// 检查是否需要扩容,realloc
	//……
}
int main()
{
	List s;
	ListInit(&s);
	PushBack(&s);
	return 0;
}

 但是有了缺省参数我们便可以一步搞定了,一开始想开多大就开多大。代码如下:

typedef  struct List
{
	int* a;
	int size;
	int capacity;
}List;

void ListInit(List* pList, int n = 4)
{
	int* a = (int*)malloc(sizeof(int) * n);
	pList->size = 0;
	pList->capacity = n;
}
int main()
{
	List s;
	ListInit(&s);//不像开辟就默认开辟四个(缺省值个)空间
	List p;
	ListInit(&p, 100);//像开辟一百个空间就开辟一百个空间
	return 0;
}

 虽然在C语言中可以用宏定义来解决,但是宏定义不够灵活。当我们每次开辟不同的空间大小时每次都要改宏,当我们要搞两个顺序表时就要定义两个宏,三个顺序表就要三个宏,非常麻烦!!!

 二,函数重载

函数重载这个概念就是祖师爷对于C语言语法的补充了。什么叫做函数重载呢?构成函数重载的条件是什么呢?下面我们就来探讨一下。

函数重载的条件

1.函数名相同

2.函数的参数类型不同or参数个数不同or参数的类型顺序不同。

 比如下面的代码:

int Add(int x, double y)
{
	return x + y;
}
//类型不同
int Add(int x, int y)
{
	return x + y;
}
//个数不同
int Add(int x, double y, int z)
{
	return x + y + z;
}
//顺序不同
int Add(double x, int y)
{
	return x + y;
}

 这些情况便构成函数重载。在判断函数重载时有一个情况是非常容易迷惑人的就是返回值不同是不会构成函数重载的!例如下列情况。

 代码:

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

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

char Add(int x, double y)
{
	return x + y;
}
//……还有很多只是返回值的类型不同的情况都不构成函数重载!

函数重载的作用

有了函数重载,那我们便可以少取名了。要使用相同功能但是数据类型or个数不同的函数时改一下参数的类型or个数or顺序就可以了!!!

三,引用

 cpp中的引用可谓是一大进步。有了引用以后指针的很多功能都能被引用代替,极大的提高了cpp程序的使用感受。既然引用如此可爱那我们一定要去认识一下它。

1.引用的格式

到底在cpp中如何写才能被称为是引用呢?

现在来看看引用的格式特点:类型+&+变量名。当你看到这样的语句时便可以知道这个变量就是一个引用。如:

int a = 1;
int& b = a;//b就是对a的一个引用。

2.引用的本质

 如果用xxx引用一个变量,有一个通俗的说法叫做给这个变量取了一个”xxx“的别名。

就比如周树人的笔名叫作鲁迅,那提到鲁迅是不是就是提到周树人呢?周树人的家门前有两棵树那鲁迅家门前有没有两棵树呢?这两个的答案当然就是肯定的,因为一个人的名字可以有很多但是人只有一个。cpp中的引用的意思就和这两个例子的意思差不多!!!现在来验证一下:

   int main()
{
	int a = 1;
	int& b = a;//b就是对a的一个引用。

	//取两者的地址验证这两个变量是否指向同一个地址
	cout << "address of a:" << &a << endl;
	cout << "address of b:" << &b << endl;

	return 0;
}

结果:

address of a:001EFB84
address of b:001EFB84

通过验证可以看到引用ba是指向同一块空间的两个不同的名字。

3.引用的特点

1.引用必须初始化

int main()
{
	int a = 1;
	int& b ;//未对引用b初始化
	return 0;
}

上面的代码就会报错。报错:

2.引用只能引用一个实体,就像人可以有很多名字但是人只有一个一样。

//引用多个实体
int main()
{
	int a = 1;
	int& b = a;

	int c = 0;
	int& b = c;
	return 0;
}

这样也会报错。报错:

但是这样是可以的,因为这是赋值:

//赋值
int main()
{
	int a = 1;
	int& b = a;

	int c = 0;
    b = c;
	return 0;
}

 3.一个实体可以有多个别名就像一个人可以有多个名字一样。

//一个实体可以有多个别名
int main()
{
	int a = 0;
	int& b = a;
	int& c = a;
	int& d = a;
	//……
	return 0;
}

4. 引用不能引用空指针

//不能引用空指针
int main()
{
	int& a = nullptr;
	return 0;
}

报错:

//不能引用空指针
int main()
{
	int& a = NULL;
	return 0;
}

报错:

四,使用引用的两种形式

 1.引用作参数(输出型参数)

当函数中的一个参数的作用是用来做输出型参数时便可以考虑使用引用做参数。

补充:

1.输出型参数:输出型参数的作用就是为了改变外面传入参数的数据。

2.输入性型参数:输入型参数就是给函数内部传入数据。

这里经典的要传输入型参数的函数就是swap函数

void swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

这个swap函数使用的是指针来交换a,b两个变量的数据。

//引用
void swap(int& a, int& b)
{
	int tmp = a;
	a = b;
	b = tmp;
}
int main()
{
	int a = 0;
	int b = 10;
	cout << "swap前a:" << a << endl;
	cout << "swap前b: " << b << endl;
	swap(a, b);//swap函数调用
	cout << endl;
	cout << "swap后a:" << a << endl;
	cout << "swap后b: " << b << endl;
	return 0;
}

结果:

swap前a:0
swap前b: 10

swap后a:10
swap后b: 0

二,引用做返回值

 用引用做返回值是一个得十分谨慎的事情。因为引用卓返回值是有前提的,前提就是出了返回值函数的作用域以后返回值的实体不能被销毁。

1.其它类型的函数返回是怎么做的呢?

图解:

 通过上面的过程n的数据便被返回到ret中接收。

2.引用作返回值

引用做返回值就和一般类型的返回不同了。因为传引用返回是不产生临时变量的。

但是在n出了函数add以后,n就被销毁了。这个时候就要看运气了。当n里面的值还没有被清理时便可以让ret接收,当n中的被清理以后ret接收的值就是随机值了。所以当返回值在被接收前是会被销毁的参数时就要谨慎使用了。

应该传引用返回的场景

 当变量是静态变量,堆上的变量,全局变量时便可以大胆的使用传引用返回。因为这些变量是不会被系统轻易销毁的。又因为使用传引用变量可以减少数据的拷贝,所以传引用返回的效率会更高。所以在可以使用传引用返回的场景应该多多使用传引用返回。

补充:利用传引用返回来修改顺序表里面的值和读取第i个位置的值。

C语言版本:

//C语言读取第i个位置的值
int Find(List* ps, int i)
{
	assert(ps);
	return ps->a[i];
}
//修改第i个位置的值
void SLModify(List* ps, int i, int x)
{
	assert(i < ps->size);
	ps->a[i] = x;
}

C++利用引用版本:


int& SLAC(List& ps,int i)
{
	assert(i < ps.size);
	return ps.a[i];
}

 从这里便可以看出cpp的引用有多香了!哈哈!

补充:

使用引用时不能发生权限的扩大。可以发生权限的平移和缩小。

如:

int main()
{
	double a = 1;
	int b = a;
}

这个程序是可以运行的,但是换成下面的代码便会报错:

int main()
{
	double a = 1;
	int& b = a;
}

这是为什么呢?这是因为,在第一个程序中双精度浮点型的a要传给整型的b就会发生如下图所示的过程:

 在双精度浮点型的a传给b时会发生隐式转换,这个过程会产生一个临时变量。临时变量有一个特点就是具有常性。所以在将a的值再赋值给b时就会发生权限的扩大!那该如何搞定这个错误呢?解决方法如下:

int main()
{
	double a = 1;
	const int& b = a;//在b前面加一个const修饰符
}

这样b便也有了常性,这样就相当于权限的平移了!

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

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

相关文章

商城-学习整理-基础-环境搭建(二)

目录 一、环境搭建1、安装linux虚拟机1&#xff09;下载&安装 VirtualBox https://www.virtualbox.org/&#xff0c;要开启 CPU 虚拟化2&#xff09;虚拟机的网络设置3&#xff09;虚拟机允许使用账号密码登录4&#xff09;VirtualBox冲突5&#xff09;修改 linux 的 yum 源…

JDK JRE JVM

JDK JRE JVM JDKJREJVM三者之间的联系三者之间的区别 JDK JDK是用于开发、编译、调试和运行Java应用程序的软件包&#xff0c;包含了Java编程语言的开发工具和Java运行时环境。JDK包括Java编译器&#xff08;javac&#xff09;、Java虚拟机&#xff08;JVM&#xff09;和Java类…

AtcoderABC246场

#A - Four PointsA - Four Points 题目大意 在平面上有一个矩形&#xff0c;矩形的每条边都平行于x轴或y轴&#xff0c;并且它的面积不为零。 给定这个矩形三个顶点的坐标 (x1, y1), (x2, y2), (x3, y3)&#xff0c;找到另外一个顶点的坐标。 思路分析 根据矩形的性质可以通…

为什么低代码只能掀起小浪花?了解低代码的得失与前景

导语&#xff1a;低代码是相对于高代码和无代码的一个中间概念&#xff0c;通常强调的是用户不需要学习如何写代码&#xff0c;就能完成工作。然而低代码模式一直不温不火&#xff0c;原因是什么呢&#xff1f;一起来看一下吧。 最近互联网大公司裁员消息又起&#xff0c;“低代…

裁剪内核和新内核available差异大原因分析

背景 host内核裁剪时会进行收益的比较&#xff0c;比如裁剪前用5.10最新内核得出内存数据&#xff0c;然后和裁剪后的内存数据进行对比。 在进行对比中&#xff0c;发现裁剪后的内存available比裁剪前多了10个G&#xff0c;有点不正常了&#xff0c;需要分析下这10个G到底是怎…

基于VORS、CCDM模型、GeoDetector、GWR模型集成技术在城镇化与生态系统健康空间关系分析及影响效应

详情点击链接&#xff1a;基于VORS、CCDM模型、GeoDetector、GWR模型集成技术在城镇化与生态系统健康空间关系分析及影响效应 第一&#xff1a;生态系统健康理论基础及研究热点分析 1.生态系统健康概念及内涵 2.生态系统健康评价方法与指标体系 3.城镇化与生态系统健康 4.…

Git使用规范Git常用命令

Git使用规范&&Git常用命令 分支规范 master分支 master的分支HEAD和历史commit均是是稳定、可发布的状态。master分支的每个commit都需要打tag&#xff0c;如v1.0、v1.1、v1.2、v2.0等。仅能从test分支和hotfix分支合并过来。 hotfix的合并必须是通过代码审核和测试…

AI数字人:图像超分辨率模型 Real-ESRGAN

1 Real-ESRGAN介绍 1.1 Real-ESRGAN是什么&#xff1f; Real-ESRGAN全名为Enhanced Super-Resolution GAN&#xff1a;增强的超分辨率的对抗生成网络&#xff0c;是由腾讯ARC实验室发布的一个盲图像超分辨率模型&#xff0c;它的目标是开发出实用的图像/视频修复算法&#xf…

oled拼接屏在柳州的户外广告中有哪些应用展现?

柳州oled拼接屏是一种高端的显示屏&#xff0c;它采用了OLED技术&#xff0c;具有高亮度、高对比度、高色彩饱和度、高刷新率等优点&#xff0c;能够呈现出更加真实、清晰、细腻的图像效果。 同时&#xff0c;柳州oled拼接屏还具有拼接功能&#xff0c;可以将多个屏幕拼接在一…

2023婴幼儿奶粉市场数据分析(天猫数据中心)

我国婴幼儿奶粉市场一直保持着相当大的规模&#xff0c;虽然近几年新生人口数量不断下降&#xff0c;但伴随消费者的消费升级不断加速、大龄孩童吃奶粉的时间延长等&#xff0c;整体来看&#xff0c;婴幼儿奶粉行业市场规模保持平稳。 根据鲸参谋电商数据分析平台的相关数据显示…

240. 搜索二维矩阵 II

题目描述&#xff1a; 主要思路&#xff1a; 利用矩阵中的单调性进行搜索。 class Solution { public:bool searchMatrix(vector<vector<int>>& matrix, int target) {int nmatrix.size(),mmatrix[0].size();int in-1,j0;while(i>0&&j<m){if(m…

Hadoop: High Available

序言 在Hadoop 2.X以前的版本&#xff0c;NameNode面临单点故障风险&#xff08;SPOF&#xff09;&#xff0c;也就是说&#xff0c;一旦NameNode节点挂了&#xff0c;整个集群就不可用了&#xff0c;而且需要借助辅助NameNode来手工干预重启集群&#xff0c;这将延长集群的停…

行为型模式 - 命令模式

概述 日常生活中&#xff0c;我们出去吃饭都会遇到下面的场景。 定义&#xff1a; 将一个请求封装为一个对象&#xff0c;使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通&#xff0c;这样方便将命令对象进行存储、传递、调用、增加与管理。 结构 …

美颜SDK与动态贴纸技术的发展趋势:向更智能、更新颖的美化

美颜SDK和动态贴纸技术在近年来迅速发展&#xff0c;成为移动应用、社交媒体和视频直播等领域中不可或缺的元素。本文将探讨美颜SDK和动态贴纸技术的最新发展趋势&#xff0c;包括智能化算法的应用、增强现实的融合以及个性化定制的兴起。我们将展望未来&#xff0c;展示这些技…

LiveGBS流媒体平台GB/T28181功能-平台国标GB28181级联上级如何抓包分析windows抓包和Linux抓包Wireshark和TCPDUMP

LiveGBS平台国标GB28181级联上级如何抓包分析windows抓包和Linux抓包Wireshark和TCPDUMP 1、背景3、抓包工具准备3.1、Linux3.2、windows 3、找到级联的上级ip4、执行命令抓级联的上级ip4.1 Linux4.2 Windwos 5、触发相关操作6、停止抓包6.1、Linux6.2、Windows 7、查看抓包8、…

【笔试训练】排序子序列和倒置字符串

目录 一、选择题 二、倒置字符串 一、选择题 一、A 派生出子类 B &#xff0c; B 派生出子类 C &#xff0c;并且在 java 源代码有如下声明&#xff1a; 1. A a0new A(); 2. A a1new B(); 3. A a2new C(); 问以下哪个说法是正确的&#xff08;D&#xff09; A. 只有第一行能通…

项目化思维

项目任务负责人的角色 整合者 管理者 影响者 明确需求和目标&#xff1a;IPAD四问法 I:Influencer关键影响人 P:Purpose目的 A:Acceptance 成功标准 时间&#xff0c;成本&#xff0c;质量 D:Deliverables 可交付物 MoSCoW原则 任务分解WBS&#xff08;work breakdown str…

【已解决】哪些软件可以解压RAR文件?

RAR文件是我们日常生活及工作中经常用的压缩文件&#xff0c;文件压缩后可以更方便储存或者传输&#xff0c;后续要使用的时候再进行解压。 那RAR文件如何解压呢&#xff1f;哪些软件可以用来解压RAR文件&#xff1f;在这一方面还是小白的小伙伴可以来看看下面的分享。 解压任…

06_本地方法接口+07_本地方法栈

一、本地方法&#xff1f; 本地方法就是Java调用非Java代码的接口。 本地方法的作用是融合不同的编程语言为Java所用&#xff0c;它的初衷是融合 C、C程序 二、为什么要使用Native Method? 三、本地方法栈 Java虚拟机栈用于管理Java方法的调用&#xff0c;而本地方法栈用于…

JVM系统优化实践(20):GC生产环境案例(三)

您好&#xff0c;这里是「码农镖局」CSDN博客&#xff0c;欢迎您来&#xff0c;欢迎您再来&#xff5e; 某新手开发工程师接到了一个保存Elasticsearch日志的任务&#xff0c;以供后续分析之用。但写代码的时候&#xff0c;误将保存日志的代码段弄成了无限循环&#xff0c;程序…