【C/C++学习笔记】引用和指针的区别

1.引用

引用:某一个变量或对象的别名,对引用的操作与对其所绑定的变量或对象的操作完全等价

(1)&不是求地址运算符,而是起标志作用
(2)引用的类型必须和其所绑定的变量的类型相同
(3)声明引用的同时必须对其初始化,否则系统会报错
(4)引用相当于变量或对象的别名,因此不能再将已有的引用名作为其他变量或对象的名字或别名
(5)引用不是定义一个新的变量或对象,因此内存不会为引用开辟新的空间存储这个引用.

#include <stdio.h>
#include <iostream>
int main() {
    int a = 1;
    int& b = a;
    //int& c; // error 引用必须设置初始值
    printf("a=%d b=%d\n", a, b);
    b++;
    printf("a=%d b=%d\n", a, b);
    system("pause");
    return 0;
}

指针:即内存地址,指针变量是用来存放内存地址的变量

(1)指向的是一个对象(内存地址)或者有效空间的地址

(2)空指针和其他无效指针

2. 引用和指针的区别

(1)引用必须被初始化,但是不分配存储空间。指针声明时可以不初始化,在初始化的时候需要分配存储空间。 
(2)引用初始化以后不能被改变,指针可以改变所指的对象。
(3)不存在指向空值的引用,但是存在指向空值的指针。
(4)当用引用作为函数的参数时,其效果和用指针作为函数参数的效果相当。当调用函数时,函数中的形参就会被当成实参变量或对象的一个别名来使用,也就是说此时函数中对形参的各种操作实际上是对实参本身进行操作,而非简单的将实参变量或对象的值拷贝给形参。

注意:引用作为函数参数时,会引发一定的问题,因为让引用作参数,目的就是想改变这个引用所
指向地址的内容,而函数调用时传入的是实参,看不出函数的参数是正常变量,还是引用,因此可能会引发错误。所以使用时一定要小心谨慎。如果不需要修改引用参数可以配合const使用。

总结:

(1)在引用的使用中,单纯给某个变量去别名是毫无意义的,引用的目的主要用于在函数参数的传递中,解决大块数据或对象的传递效率和空间不如意的问题.
(2)用引用传递函数的参数,能保证参数在传递的过程中不产生副本,从而提高传递效率,同时通过const的使用,还可以保证参数在传递过程中的安全性。
(3)引用本身是目标变量或对象的别名,对引用的操作本质上就是对目标变量或对象的操作。因此能使用引用时尽量使用引用而非指针

补充:

1.左值和右值

在C++11中可以取地址的、有名字的就是左值,反之,不能取地址的、没有名字的就是右值(将亡值或纯右值)。

举例:int a = b+c, a 就是左值,其有变量名为a,通过&a可以获取该变量的地址;表达式b+c、函数int func()的返回值是右值,在其被赋值给某一变量前,我们不能通过变量名找到它,&(b+c)这样的操作则不会通过编译。

  • 左值是可以放在赋值号左边可以被赋值的值;左值必须要在内存中有实体;
  • 右值当在赋值号右边取出值赋给其他变量的值;右值可以在内存也可以在CPU寄存器。
  • 一个对象被用作右值时,使用的是它的内容(值),被当作左值时,使用的是它的地址。

2.左值引用

左值引用就是我们平常使用的“引用”。引用是为对象起的别名,必须被初始化,与变量绑定到一起,且将一直绑定在一起。

我们通过 & 来获得左值引用,
type &引用名 = 左值表达式;
可以把引用绑定到一个左值上,而不能绑定到要求转换的表达式、字面常量或是返回右值的表达式。举个例子:

int i = 42;
int &r = i;    //正确,左值引用
int &r1 = i * 42;   //错误, i*42是一个右值
const int &r2 = i * 42; //正确,可以将一个const的引用绑定到一个右值上

3.右值引用

右值引用是C++11中引入的新特性 , 它实现了转移语义和精确传递。

它的主要目的有两个方面:

  • 消除两个对象交互时不必要的对象拷贝,节省运算存储资源,提高效率。能够更简洁明确地定义泛型函数。
  • 右值引用就是必须绑定到右值的引用,他有着与左值引用完全相反的绑定特性,我们通过 && 来获得右值引用。

C++之所以设计出右值引用的语法,主要是因为对于类似b+1;这样的运算是发生在CPU寄存器上的,就不能对其取地址、赋值等操作,所以这类运算只能放在等号的右边,将其赋给其他的变量。若等号右边出现:&b,这样的操作是,也是右值,因为取地址符的操作也是在寄存器中完成的。所以不能作为左值。

右值引用的基本语法:

type &&引用名 = 右值表达式;

右值有一个重要的性质——右值只能绑定到一个将要销毁的对象上。举个例子:

int  &&rr = i;  //错误,i是一个变量,变量都是左值
int &&rr1 = i *42;  //正确,i*42是一个右值

右值引用和左值引用的区别

  1. 左值可以寻址,而右值不可以。
  2. 左值可以被赋值,右值不可以被赋值,可以用来给左值赋值。
  3. 左值可变,右值不可变(仅对基础类型适用,用户自定义类型右值引用可以通过成员函数改变)。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值