c++学习——引用变量和指针变量的区别

1.指针可以被多次绑定,而引用不能

引用跟一个对象绑定后,直到那个对象生命周期结束,都不能绑定到其他对象。

看这么一个例子:

int i= 2;

int j = 4;

int &ri = i;

ri = j;

j = 8;

通过结果可知,此时i=ri=4,说明ri并没有绑定到j上,而刚才ri=j只是简单的赋值操作,虽然在vs下能顺利编译通过。

因此引用变量是从一而终的,因此必须在声明时就确定引用的对象。

2.引用不一定都是安全的

可能有人会觉得既然引用变量不能为空或是NULL,是不是引用就比指针就安全得多呢。大多数情况下是的,但也没想象中的那么安全,因为我们还是有很多种办法可以使它空引用。看下面的一个例子

int *pi;

int &ri=*pi;

3.引用变量&到底是什么

引用一开始学习C++时很经典的一个例子

//通过引用方式传递的是真真切切的对象,既不是对象的拷贝也不是对象的地址

void swap_reference(int &v1, int &v2){

    int temp = v1;

    v1 = v2;

    v2 = temp;

}

//swap_pointer(v1, v2)由于是对地址的操作,可以达到互换的目的

void swap_pointer(int *v1, int *v2){

    int temp = *v1;

    *v1 = *v2;

    *v2 = temp;

}

//swap函数时,互换的是函数空间内的两个值,可认为是v1,v2的两个拷贝互换了

void swap(int v1, int v2){  

    nt temp = v1;

    v1 = v2;

    v2 = temp;

}

可以认为,变量a和变量c就是同一个变量,因为二者的值、址,以及在程序中的作用方式完全一致,因此在C++ Primer中说“引用变量就是变量的别名”。但不同之处在于,引用变量要有初始化过程。

intmain(){

inta=1;

cout<<"普通变量:"<<"值:"<<a<<" 址:"<<&a<<endl;

int*b=&a;

cout<<"指针变量:"<<"值:"<<b<<" 址:"<<&b<<endl;

int&c=a;

cout<<"引用变量:"<<"值:"<<a<<" 址:"<<&c<<endl;

return0;

}

普通变量:值:1址:0x6dfef8

指针变量:值:0x6dfef8址:0x6dfef4

引用变量:值:1址:0x6dfef8


这里做一下总结:变量对应着某个存储单元,具有地址和值。对普通变量的访问,访问的是它的值;而对指针变量的访问(*操作),访问的是它所指向的变量的值;引用变量就是变量别名。此外,我们说普通变量和指针作为函数参数时,是传值,而引用变量才是传址。所谓传值,是指改变形参变量的内容,而传址,是指改变形参变量的地址,也就是改变它所对应的存储单元。指针寻址方式,对于计算机实现来说很容易,但对于人理解却不太容易。这可能是Java中不采用指针的原因之一吧,但实际上Java中的引用就是C++中的指针,遗憾的是,Java中没有C++中的指针,在一些情况下会使得代码比较复杂。

实例算法:

示例:

#include <iostream>

using namespace std;

 int main(){   

 int  var;    // 声明int类型变量var    

int * ptr;    // 声明指针变量ptr    

ptr = &var;  // 先使用 & 运算符获取变量var的地址,再把该地址赋值给指针变量ptr    

int ** pptr;  // 声明二级指针变量pptr    

pptr = &ptr;  // 先使用 & 运算符获取变量ptr的地址,再把该地址赋值给二级指针变量pptr    

int & ref1 = var;  // 声明引用变量ref1, ref1是变量var的别名(引用必须在创建时被初始化)    

int & ref2 = *ptr;  // 先使用*运算符获取指针变量ptr所指向的变量(即var),再用该变量(var)初始化引用变量ref2(声明引用变量ref2的同时对它进行初始化)。也就是说,该行代码执行后,ref2也是变量var的别名 var = 20    

    cout << "Value of var: ";

    cout << var << endl;

    cout << "Value of &var: ";

    cout << &var << "\t(var的地址)" << endl;

    cout << endl;

    cout << "Value of ptr: ";

    cout << ptr << "\t(等于&var)" << endl;

    cout << "Value of *ptr: ";

    cout << *ptr << "\t\t(等于var)" << endl;

    cout << "Value of &ptr: ";

    cout << &ptr << "\t(ptr的地址)" << endl;

    cout << endl;

    cout << "Value of pptr: ";

    cout << pptr << "\t(等于&ptr)" << endl;

    cout << "Value of *pptr: ";

    cout << *pptr << "\t(等于ptr, 等于&var)" << endl;

    cout << "Value of **pptr: ";

    cout << **pptr << "\t\t(等于*ptr, 等于var)" << endl;

    cout << "Value of &pptr: ";

    cout << &pptr << "\t(pptr的地址)" << endl;

    cout << endl;

    cout << "Value of ref1: ";

    cout << ref1 << "\t\t(等于var)" << endl;

    cout << "Value of &ref1: ";

    cout << &ref1 << "\t(等于&var)" << endl;

    cout << endl;

    cout << "Value of ref2: ";

    cout << ref2 << "\t\t(等于var)" << endl;

    cout << "Value of &ref2: ";

    cout << &ref2 << "\t(等于&var)" << endl;

    return 0; }

输出结果:

Value of var: 20

Value of &var: 0x7ffce63490bc    (var的地址)

Value of ptr: 0x7ffce63490bc    (等于&var)

Value of *ptr: 20        (等于var)

Value of &ptr: 0x7ffce63490b0    (ptr的地址)

Value of pptr: 0x7ffce63490b0    (等于&ptr)

Value of *pptr: 0x7ffce63490bc    (等于ptr, 等于&var)

Value of **pptr: 20        (等于*ptr, 等于var)

Value of &pptr: 0x7ffce63490a8    (pptr的地址)

Value of ref1: 20        (等于var)

Value of &ref1: 0x7ffce63490bc    (等于&var)

Value of ref2: 20        (等于var)

Value of &ref2: 0x7ffce63490bc    (等于&var)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容