2-5:C++快速入门之引用,引用和指针的区别
Posted 快乐江湖
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2-5:C++快速入门之引用,引用和指针的区别相关的知识,希望对你有一定的参考价值。
在第一次学习C语言指针时,许多教材上都会给出一个交换变量值的函数的例子,开始我们认为这样交换就可以成功
void swap(int a,int b)
{
int temp=a;
a=b;
b=temp;
}
int main()
{
int a=1;
int b=2;
swap(a,b);
}
但学习完指针后,就明白了这样的操作是不行的,因为每当调用函数时就会为该函数的形参开辟一个新的空间,函数结束之后,形参的空间也就被销毁了,所以不可能交换成功。于是正确的写法应该是这样
void swap(int* x,int* y)
{
int temp=*x;
*x=*y;
*y=temp;
}
int main()
{
int a=1;
int b=2;
swap(&a,&b);
}
而在C++中我们引入一个新的概念——引用
(1)引用的概念
简单点来说:引用就是起别名,这一片内存空间名字叫a,然后再给它额外起一个名字,叫做b,a和b操控的是同片内存空间。
从下面的这个动态调试的过程中,大家可以深刻的体会到引用这种取别名的意思
(2)引用的特点
- 引用在定义时必须初始化,不初始化有点像野指针的感觉
- 一个变量可以有多个引用,也就是有多个外号
- 一个引用一旦引用了一个实体,就不能再引用其他实体了。
(3)常引用
C语言中我们就知道,如果定义一个常整形,表示这个整形变量是不可以修改的,所以如果用普通引用去引用就会出错
int main()
{
const int a=10;
int& b=a;//错误,权限被放大,之前只可读,赋值后却可读可写了
}
那么面对这样的变量,如果仍然使用之前的引用方式是不可行的,这涉及到一个权限问题,变量a自身只能可读,但是它被int& b
引用后,反倒可以修改了,这就矛盾了。所以要解决这种权限问题,必须使用常引用
int main()
{
const int a=10;
const int& b=a;//常引用
}
- 指针和引用在赋值时,权限不能放大,但是可以缩小(这也就是为什么
int strlen(const char* str
)中形参是const类型的)
int main()
{
int a=10;
const int& b=a;//这样的做法是可以的,权限被缩小的
}
- 常数具有常性,所以引用常数时,必须使用常引用
int main()
{
int& c=1;//错误
const int& c=1;//正确
}
- C语言中,浮点型转换为整型时,有一个中间过程,会涉及到一个中间变量,这个中间变量具有常性,必须使用常引用
int main()
{
double a=3.14;
int b=a;//隐式转换
//如果用int型引用double型,引用的不是那个double,而是double转换为int时
//的那个中间变量,因为它具有常性
int& ps=a;//错误
const int& ps=a;//正确
}
关于常引用,确实C++在这方面有点麻烦,但是这个常引用也是有好处的,尤其体现在引用做形参。我们一般使用常引用作为形参,根据以上叙述,所以其实参可以是变量也可以是常量,同时如果实参和形参存在类型转换,这也是无妨的,也可以传递
void test(const DataType& x)
{
//形参使用常引用好处多多
}
(4)引用的应用场景
A:做参数
回到之前的情境导入,根据以上的叙述在C++中交换两个变量的值就可以使用引用了。
void Swap(int& x,int &y)
{
int temp=x;
x=y;
y=temp;
}
int main()
{
int a=1;
int b=2;
Swap(a,b);
}
B:做返回值
实参传给形参时,如果不用指针或引用,那么形参就要拷贝一份,这一点相信大家是很明白的。但其实函数的返回值也属于传值,也就是它不是直接返回给调用函数的变量,而是先给寄存器或内存(如果数据大的话要开辟更多空间)
所以,引用也可以用于返回值。让函数返回引用,在让调用它的地方引用,相当于一次拷贝。
其实上面的代码是有一定的问题,虽然可以正确执行,通过调试可以发现,receive和ret地址是一样的,他们都是那一片内存空间的别名。
如果在后面再调用一次sum函数,最终输出结果成了7了
使用调试,会感受到这个过程
而如果再加入一句毫不相干的代码,会发现最后输出的竟然是一个随机值,这是因为到这里的时候ret早就还给系统了。
所以:如果函数返回时,已经出了作用域,此时如果返回对象还未归还给系统,那么可以使用引用返回,但是如果已经还给系统了,则必须使用传值返回。
(5)引用和指针
语法角度上讲,引用是实体的别名,与实体共用统一内存空间,而从底层实现角度上讲,引用其实是按照指针的方式进行的
从汇编角度可以看出这一点
引用和指针的区别如下
引用 | 指针 |
---|---|
引用定义必须初始化 | 指针没有要求 |
引用只能一个实体 | 指针在任何时候指向任何同类型的实体 |
没有NULL引用 | 但有NULL指针 |
使用sizeof()表示引用类型的大小 | 使用sizeof表示地址空间所占字节数 |
++引用表示引用的实体增加1 | ++指针表示指针向后偏移一个类型的大小(字节) |
没有多级引用 | 但有多级指针 |
引用较安全 | 指针较不安全 |
以上是关于2-5:C++快速入门之引用,引用和指针的区别的主要内容,如果未能解决你的问题,请参考以下文章