C++中指针和引用的区别&&传值、传址、传引用的区别,哪一种高效?

一、概念

  • 指针:指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元。
  • 引用:引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已。

举个例子:

int a=10;
//指针,定义了一个整型变量a和指针变量p,该指针变量指向a的存储单元,即p的值是a存储单元的地址。
int* p=&a;
//引用,一个整形变量a和这个整形a的引用b,事实上a和b是同一个东西,在内存占有同一个存储单元。
int& b=a;
  • 引用的特性:

(1)引用在定义时必须初始化;
(2)一个变量可以有多个引用;
(3)引用一旦绑定了一个实体,就不能再改变为其它变量的引用。

二、引用和指针的区别与联系

1.相同点

这里写图片描述

2.不同点

(1)引用定义时必须初始化,指针可以不用初始化;
(2)引用一旦初始化为指向一个对象,就不能再指向其他对象,而指针可以在任何时候指向任何一个同类型的对象;
(3)没有空引用,但是有空指针;
(4)在sizeof中的含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节的个数(在32为平台下,指针求sizeof永远是4);
(5)引用++改变的是变量的内容,指针++改变的是指针的指向;
(6)有多级指针,但没有多级引用;
(7)引用使用起来比指针更安全;
(8)如果返回动态内存分配的对象或者内存,必须使用指针,引用可能引起内存泄漏;

三、传值、传址、传引用的区别,哪个更高效?

1.传值
  • 这种传递方式中,实参和形参是两个不同的地址空间,参数传递的实质是将原函数中变量的值,复制到被调用函数形参所在的存储空间中,这个形参的地址空间在函数执行完毕后,会被回收掉。整个被调用函数对形参的操作,只影响形参对应的地址空间,不影响原来函数中的变量的值,因为这两个不是同一个存储空间。
    即使形参的值在函数中发生了变化,实参的值也完全不会受到影响,仍为调用前的值。
2.传址
  • 这种参数传递方式中,实参是变量的地址,形参是指针类型的变量,在函数中对指针变量的操作,就是对实参(变量地址)所对应的变量的操作,函数调用结束后,原函数中的变量的值将会发生改变。
    被调用函数中对形参指针所指向的地址中内容的任何改变都会影响到实参。
3.传引用
  • 这种参数传递方式中,形参是引用类型变量,其实就是实参的一个别名,在被调用函数中,对引用变量的所有操作等价于对实参的操作,这样,整个函数执行完毕后,原先的实参的值将会发生改变。
    被调函数对形参做的任何操作都影响了主调函数中的实参变量。
4.哪一种更高效?
  • 在内置类型当中三种传递方式的效率上都差不多;
  • 在自定义类型当中,传引用的更高效一些,因为它没有对形参进行一次拷贝

四、常引用

  • 我们来进一步理解引用:
    int &a=b 相当于 int const a=b。即引用是一个指针常量(又称常指针,即一个常量,其类型是指针)。 每当编译器遇到引用变量a,就会自动执行 操作。
    常引用:const int &a=b就相当于 const int * const a=b。不仅仅是a这个地址不可修改,而且其指向的内存空间也不可修改。
 #include<iostream>
using namespace std;

void main()
{
    //变量初始化,再const引用 变量
    int b = 10;
    const int &a = b;
    b = 11;
    //b是可以修改的,但是a不能修改
    printf("a=%d,b=%d\n", a, b);
    system("pause");
}
  • 除此之外,常引用还有一个作用,我们来看一段代码
float fNum4 = 10.0f;
//int &iNum5 = fNum4;int来接收float的值,编译器会报错
const int &iNum5 = fNum4;
//常引用就会避免这种情况

五、引用的使用场景

1.给变量起别名
int a;       //定义 a 是整型变量
int &b = a;  //声明  b 是 a 的引用
2.将引用作为函数的参数

使用引用类型就不必再swap中声明形参是指针变量,指针变量要另外开辟内存单元,其内容是地址。而引用变量不是一个独立的变量,不单独占内存单元。而且在调用swap函数时,只需要传值即可,将引用作为函数的形参更加简单、直观、方便。

void swap(int &a, int &b)
{
    int temp;                               
    temp = a;                                
    a = b;                                   
    b = temp;
}

注意:
const+引用可以提高程序的安全性和效率。

3.返回值
// 值返回
int Add(int _iLeft, int _iRight)
{
return _iLeft + _iRight;
} 
// 引用 返回
int& Add(int & _iLeft, int& _iRight)
{
int iResult = _iLeft+_iRight;
return iResult;
}

注意:
将引用作为函数的返回值,返回值的生命周期必须长于函数的生命周期,且不能反回栈空间上的引用。

猜你喜欢

转载自blog.csdn.net/cherrydreamsover/article/details/81839010