C++入门学习(2)

思维导图:

一,缺省参数

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

#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: 10swap后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.mzph.cn/news/1756.shtml

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

相关文章

【个人笔记】linux命令之ls

目录 Linux中一切皆文件ls命令常用参数常用命令lscpu lspci Linux中一切皆文件 理解参考&#xff1a;为什么说&#xff1a;Linux中一切皆文件&#xff1f; ls命令 ls&#xff08;英文全拼&#xff1a; list directory contents&#xff09;命令用于显示指定工作目录下之内容…

实现大文件传输的几种方法,并实现不同电脑间大文件传输

随着网络技术的快速发展&#xff0c;大文件的传输需求越来越多&#xff0c;如何在不同的电脑之间实现大文件的快速传输&#xff0c;是一个挑战&#xff0c;下面介绍几种常用的方法可以解决这个问题。 1、利用局域网传输&#xff1a;把两台电脑接入同一个网络环境&#xff0c;通…

每天一道大厂SQL题【Day27】脉脉真题实战(三)连续两天活跃用户

文章目录 每天一道大厂SQL题【Day27】脉脉真题实战(三)连续两天活跃用户每日语录第26题 中级题: 活跃时长的均值1. 需求列表思路分析 答案获取加技术群讨论附表文末SQL小技巧 后记 每天一道大厂SQL题【Day27】脉脉真题实战(三)连续两天活跃用户 大家好&#xff0c;我是Maynor。…

AtCoder Beginner Contest 310-D - Peaceful Teams(DFS)

Problem Statement There are N sports players. Among them, there are M incompatible pairs. The i-th incompatible pair (1≤i≤M) is the Ai​-th and Bi​-th players. You will divide the players into T teams. Every player must belong to exactly one team, an…

Web3.0:重新定义数字资产的所有权和交易方式

随着区块链技术的发展和应用&#xff0c;数字资产的概念已经逐渐深入人心。数字资产不仅包括加密货币&#xff0c;还包括数字艺术品、虚拟土地、游戏道具等各种形式的数字物品。然而&#xff0c;在传统的互联网环境下&#xff0c;数字资产的所有权和交易方式往往受到限制和约束…

SQL中为何时常见到 where 1=1?

你是否曾在 SELECT 查询中看到过 WHERE 11 条件。我在许多不同的查询和许多 SQL 引擎中都有看过。这条件显然意味着 WHERE TRUE&#xff0c;所以它只是返回与没有 WHERE 子句时相同的查询结果。此外&#xff0c;由于查询优化器几乎肯定会删除它&#xff0c;因此对查询执行时间没…

猿创征文|一文带你了解前端开发者工具

前端开发者工具目录 一、前言二、前端开发者工具——编译器&#xff08;含插件&#xff09;1、VS Code2、VS Code 必备插件3、WebStorm 三、前端开发者工具——UI 框架工具1、Element2、Vant 四、前端开发者工具——API 调试工具1、ApiPost 五、写在最后&#xff08;总结&#…

微服务sleuth+zipkin---链路追踪+nacos配置中心

目录 1.分布式链路追踪 1.1.链路追踪Sleuth介绍 1.2.如何完成sleuth 1.3.zipkin服务器 2.配置中心 2.1.常见配置中心组件 2.2.微服务集群共享一个配置文件 2.2.1实时刷新--配置中心数据 2.2.2.手动写一个实时刷新的配置类 ----刷新配置文件 2.3.多个微服务公用一个配…

【最新教程】树莓派安装系统及VNC远程桌面连接

大家好&#xff0c;今天就不给大家介绍PYTHONL ,今天我作为一个刚入坑树莓派的小白&#xff0c;整理了一下自己安装树莓派的整个过程&#xff0c;分享给大家。 目录 树莓派 准备工作&#xff1a; 树莓派远程ssh失败access denied 原因&#xff1a; 树莓派系统安装 1、下载…

初识C++(上)——“C++”

各位CSDN的uu们你们好呀&#xff0c;小雅兰的全新专栏又来啦&#xff0c;这次的专栏主要介绍的是C&#xff0c;下面&#xff0c;让我们进入C的世界吧&#xff01;&#xff01;&#xff01; 什么是C C语言是结构化和模块化的语言&#xff0c;适合处理较小规模的程序。对于复杂的…

vue---自定义指令

局部自定义指令 <div idapp>原数据: <span v-text"num"></span>放大十倍的数据<span v-big"num"></span></div><script>const app new Vue({el: #app,data: {num: 1},directives: {big: {bind(el, binding) {c…

day27 贪心算法

1.什么是贪心&#xff1f; 比如10张钞票&#xff0c;有1&#xff0c;5&#xff0c;20&#xff0c;100等面额&#xff0c;取五张&#xff0c;如何取得到数额最多的钱&#xff1f;每次取面额最大的那张钞票&#xff1b;就是每个阶段的局部最优&#xff1b;全局最优就是最后拿到的…

ETHERCAT转ETHERCAT网关西门子为什么不支持ethercat两个ETHERCAT设备互联

1.1 产品功能 远创智控YC-ECT-ECT是自主研发的一款ETHERCAT从站功能的通讯网关。该产品主要功能是将2个ETHERCAT网络连接起来。 本网关连接到ETHERCAT总线中做为从站使用。 1.2 技术参数 1.2.1 远创智控YC-ECT-ECT技术参数 ● 网关做为ETHERCAT网络的从站&#xff0c;可以连接…

系统学习Linux-搭建基础服务器实验集合

实验分析 主机DHCP分配静态253地址&#xff0c;需配置网关主机DNF静态分配252地址域名机dhcp自动分配地址要求251中继主机添加成两块网卡并配置两个网段的网卡地址DNS解析域名并把客户机251装apache、tomcat、ngnix并把根目录设置成web下 一、搭建DHCP服务器 vm1网卡 配置网…

JDK、JRE、JVM三者之间的关系以及区别

一、关系 JDK JRE Java 开发工具包 [Java,Javac,Javadoc,Javap等] JRE JVM Java 的核心类库 二、JDK,JRE与JVM介绍 1、JDK JDK是用于Java程序开发的最小环境&#xff0c;包含&#xff1a;Java程序设计语言&#xff0c;Java虚拟机&#xff08;JVM&#xff09;&#xff0…

Spring:Bean生命周期

Bean 生命周期生命周期 Bean 生命周期是 bean 对象从创建到销毁的整个过程。 简单的 Bean 生命周期的过程: 1.实例化(调用构造方法对 bean 进行实例化) 2.依赖注入(调用 set 方法对 bean 进行赋值) 3.初始化(手动配置 xml 文件中 bean 标签的 init-method 属性值,来指…

集成算法的参数空间与网格优化

目录 1. 探索参数空间 1.1 学习曲线 1.2. 决策树对象Tree 2. 使用网格搜索在随机森林上进行调参 1. 探索参数空间 随机森林集成算法的超参数种类繁多、取值丰富&#xff0c;且参数之间会相互影响、共同作用于算法的最终结果&#xff0c;因此集成算法的调参是一个难度很高的过…

【Matlab】智能优化算法_麻雀搜索算法SSA

【Matlab】智能优化算法_麻雀搜索算法SSA 1.背景介绍2.数学模型3.文件结构4.伪代码5.详细代码及注释5.1 Get_Functions_details.m5.2 main.m5.3 SSA.m 6.运行结果7.参考文献 1.背景介绍 麻雀通常是群居的鸟类&#xff0c;有很多种类。它们分布在世界的大部分地区&#xff0c;喜…

【【51单片机的蜂鸣器-11】】

51单片机的蜂鸣器 DS1302我一直有问题搁置了几百天了 先来看看蜂鸣器 搞了一个礼拜verilog然后出去吃饭 估计自己得有10多天没看c语言和51单片机了 现在先处理一下蜂鸣器的问题 蜂鸣器 蜂鸣器分为有源蜂鸣器和无源蜂鸣器 有源内部自带震荡源&#xff0c;将正负极接上直流电压…

Spring的创建和使用

文章目录 一、通过Maven创建一个Spring项目准备工作&#xff08;第一次需要配置&#xff09;1.创建一个Maven项目2.引入依赖&#xff08;spring-context、spring-beans&#xff09;3.添加启动类 二、存储Bean对象1.创建一个Bean对象2.把Bean对象存储到Spring中 三、获取Bean对象…