当前位置 : 主页 > 编程语言 > c语言 >

C++入门-3

来源:互联网 收集:自由互联 发布时间:2023-09-03
今天,继续和大家分享关于引用的相关,以及更多关于C++入门的知识,包括内联函数,关键子auto,范围for和空指针。 以上就是我们本篇文章要了解的知识大纲,好了,我们现在继上篇

今天,继续和大家分享关于引用的相关,以及更多关于C++入门的知识,包括内联函数,关键子auto,范围for和空指针。

以上就是我们本篇文章要了解的知识大纲,好了,我们现在继上篇文章继续了解引用的相关知识。

引用

上篇文章我们提到了

引用的三个重要特性:

第一点是:引用在定义的时候必须进行初始化,如下图所示

C++入门-3_内联函数

第二点是:一个变量可以有多个引用。什么意思呢?我们以下图变量x为例,变量x既可以叫a,也可叫b。a和b都是对x的引用

C++入门-3_编译器_02

第三点:引用一旦引用了一个实体,就不能再引用其他的实体了。通俗来说,就是我给李华取了个绰号叫小华,就不能叫别人小华了。不然,很容易搞混,不清楚谁是谁。让我们来看看具体的代码:

C++入门-3_编译器_03

以上是引用的三个重要特性,接下来,我们看看下面这张图:

C++入门-3_编译器_04

从图中我们不能难发现,变量y的定义是错误的,而变量x的定义是正确的。这是为什么呢?这是因为数字10是常量,具有常性,不能更改。而我们现在给10取别名为y,y可以修改,如果y修改成功了,也就是10修改成功了,这不是扯蛋吗?所以,对于常量的引用我们需要加上const进行修饰,而对常量的引用,我们称之为常引用

引用的使用场景

引用的使用场景,主要有两个。

第一个是做参数。引用做参数,我们可以直接对外部变量进行操作。其实,引用的引入是为了简化指针的一些繁琐操作,以前我们c语言在函数中想要对外部成员进行操作,又是取地址,又是一级指针,二级指针的,甚是麻烦,还容易出错。这就有了引用,甭管你是几级指针,引用都能解决。

C++入门-3_空指针_05

引用作为参数有一个优势:提高效率(一些自定义类型会比较大,使用引用,就不需要对某个数据再进行拷贝,可以直接对相关数据进行访问,这样一来减小了空间时间上的开销,大大提高了效率)

第二个是做返回值。

C++入门-3_内联函数_06

引用作为返回值的优势,其实,也是提高效率。对于一些大的类型,能使用引用就使用引用(主要还是依照情况而定)。

引用基本任何场景下,都能使用,但是要注意,引用的对象实体出了作用域(也可以理解为函数结束),还存不存在。如果不存在,还使用引用就会造成非法访问。

以上是引用的两个主要的使用场景,在这些场景的使用过程中,会涉及到一些权限问题。

引用的权限问题

我们先看一下,下图的引用是否存在问题

C++入门-3_内联函数_07

从图中我们可以看出,编译器已经标识红线报错了。这是为什么呢?这是由于变量a被const修饰,表示不能被更改。而变量b是对a的引用,并没有用const修饰,权限被放大,出现了冲突。我本身不可以修改,而到了你哪里就可以修改了,这不是扯蛋吗?

那下面这种方式,是否存在问题呢?

C++入门-3_内联函数_08

从图中我们不难发现编译器并没有报错提示,说明这种方式是合法的。有些不细心的同学就会问,为啥,前面那种情况会出现问题,而上面这种却合法呢?当我们细心查看时,不难发现,变量d并不是对变量c的引用,只是对变量c的拷贝,这并不涉及权限的放大的问题。

我们来看看下面这种情况是否存在问题:

C++入门-3_空指针_09

从上图我们不难发现,编译器并没有进行报错。这是为什么呢?这是因为在引用的过程,权限的缩小和平移是被认可的。

那下面这种情况是否符合权限的平移或缩小呢?很明显,答案是否定的。

C++入门-3_空指针_10

一些细心的同学就会发现,它们的类型不同,那报错的原因是不是如此呢?

C++入门-3_内联函数_11

从上图看,编译器很明显没有报错,我们刚刚的猜想是错的。那原因出在哪呢?这是由于变量e赋值给变量b时,发生了类型转换,由double变成int,而类型的转换会生成临时变量,而临时变量具有常性,也就是不能被修改,所以,需要加上const修饰。

C++入门-3_空指针_12

这种情况,还会在做返回值的时候出现。

C++入门-3_空指针_13

从上图中,我们不难发现,编译器报错了,这种情况与前面的一种情况类似,值返回,产生了临时变量,而临时变量具有常性,属于权限被放大了,我们可以用下面两种方式解决。

C++入门-3_内联函数_14

C++入门-3_编译器_15

通过对引用权限问题的学习,我们发现引用的出现并不都是好的,也存在弊端。接下来,我们探讨一下,指针和引用的区别

指针和引用的区别

首先,第一点:从语法层面看,指针需要开辟空间,而引用不需要。从底层看,引用是通过指着实现的,两者都需要开辟空间。

第二点:引用必须初始化,指针可以不初始化

第三点:引用一旦引用实体就不可以改变了,而指针可以改变所指向的对象

第四点:有多级指针,但没有多级引用

第五点:没有NULL引用,但是又NULL指针

第六点:引用相对于指针更安全

第七点:访问实体的方式不同,指针需要显示访问,引用由编译器自动处理

第八点:sizeof计算引用,所引用实体类型的大小,而计算指针,始终是计算指针类型的大小

第九点:引用自身加1,是引用实体加1。而指针自身加1,是指针向后偏移一个类型的大小

关于引用,我们就先学到这。

接下来,我们来了解一下,内联函数

内联函数

宏相信大家都不陌生,就是将某些值替换成相应的英文名称,写到程序中。内联函数,也是类似的。当我们写的程序中,有使用内联函数,编译器就会将使用内联函数的地方,用该内联函数的实现方式替换掉,通俗说,将函数展开。而我们把这种会在编译过程中展开的函数,称之为内联函数

对于内联函数,我们该如何定义呢?方法很简单,在函数定义前加上inline。这里需要注意:内联函数的声明和定义不能分开

C++入门-3_内联函数_16

我们加上inline后,函数是不是一定是内联函数呢?当然不是,编译器并不相信我们。只有那些短小的函数,才适合做内联函数。但并不是每个人都会遵守规定,有些人会在一个非常长的函数前加上inline,如果让这个函数成为内联函数,会造成程序执行效率极大降低。所以,一个函数,是否成为内联函数,编译器说的算。

关于内联我们就先学到这,接下来,我们来了解C++的一个关键字auto

关键字auto

auto这个关键子对于初学者用处不大,但到了后面,十分好用。好用在呢?它可以自动推导等号右边的类型。这样干着讲体会不到它的妙处,让我们来看看代码:

C++入门-3_内联函数_17

从上图中,我们可以感受到auto的优势和便捷,今后,还会有更长的类型,这时候使用auto就非常的方便。对于auto的使用,我们需要注意它不能作为函数参数、返回值,以及数组的直接类型

对于auto,它常会于范围for结合使用

范围for

范围for是一个语法它,可以帮助我们更加便捷的访问一段范围的数据。让我们来看看它的效果。

C++入门-3_内联函数_18

从图中看,相信屏幕前的你,已经感受到它的魅力了吧。范围for会自动判断结束,自动迭代,依次取出数组的值赋给变量e。

对于范围for的使用条件,就是有具体的范围。对于数组而言就是第一个元素到最后一个元素。对于类就是begin()到end()。

对于范围for的知识,我们就先了解到这。

接下来,我们了解一下nullptr.

nullptr

对于空指针NULL,相信大家都不陌生。在传统的C头文件(stddef.h)的空指针NULL,它的本质是一个宏,内容是0。

C++入门-3_编译器_19

这就导致了一些问题的出现,比如下面这种:

C++入门-3_内联函数_20

从图中,我们可以看到,我们本意是通过NULL来调用fun(int*),但由于NULL被定义为0,这就导致了程序与现实相悖。为了解决这一问题,C++就引用了nullptr来作为空指针。

好了,到这里,本次的分享就到此结束了,不知道我有没有说明白,给予你一点点收获。如果你有所收获,别忘了给我点个赞,这是对我最好的回馈,当然你也可以在评论发表一下你的收获和心得,亦或者指出我的不足之处。如果喜欢我的分享,别忘了给我点关注噢。

网友评论