C++又很多复合类型,本文介绍两种指针和引用
引用
引用是一种复合类型,C++11新增加了一种引用“右值引用”,常用的引用是“左值引用”。
引用的定义:int n; int &r = n;
引用底层是一个指针,对指针能有什么操作,引用就可以有什么操作。引用不是一个对象,只能在定义的时候初始化,绑定一个对象。
引用必须初始化,再定义引用时,程序把引用和它的初始值绑定到一起。一旦完成初始化,引用将和它的初始值对象一直绑定到一起。因此无法令引用重新绑定到另外一个对象。对引用重新赋值后,引用的绑定的对象并没有变,而是通过引用改变了引用绑定对象的内容(毕竟引用的底层实现是指针)
下面的例子:
int n = 0,m = 1;
int &r = n;
cout << "r = "<< r << " m = "<< m <<" n ="<<n<<endl;
cout << "n的地址:" << &n << " m的地址:" << &m << " r的地址为:" << &r << endl;
r = m;
cout << "r = " << r << " m = " << m << " n =" << n << endl;
cout << "n的地址:" << &n << " m的地址:" << &m << " r的地址为:" << &r << endl;
运行结果如下:
运行结果
根据上面的结果,引用r绑定n,r的地址和n的相同;
r=m之后,r的地址依然和n的地址一样,证明r并没有改变他绑定的对象;
r=m之后,r的值和n的值都变成了m的值,证明r=m只是通过m来改变引用r以及它绑定的对象的值。
指针
指针是一种复合类型,本身是一个对象,存放某个对象的地址。
定义指针:int n; int *p; p = &n;
指针和引用有许多的包不同点:
其一:指针本身就是一个对象,允许对指针赋值和拷贝,而且在指针的生命周期内塔可以先后指向几个不同的对象;
其二:指针无需在定义时值。和其他的内置类型一样,在块作用域定义内的指针没有初始化,也拥有一个不确定的值。
空指针:
int *p1 = nullptr;
int *p2 = 0;
以上两个空指针的定义是相同,nullptr是c++11标准引入的值,它是一种特殊类型的字面值,可以被转换成任意其他类型的指针。也可以通过将指针初始化字面值0来生成空指针。对指针进行一系列的操作后,直接赋值为0,它就不指向任何对象了,例如p2 = 0。
过去的程序还会用到一个名为NULL的预处理变量来给指针赋值,这个变量在头文件cstdlib中定义,它的值就是0。
指针有==和!=的操作,比较的结果是布尔类型,如果两个指针存放的地址值相等,反之,他们不相等。
指针相等有以下三种可能:
- 他们都为空。
- 他们都指向了同一个对象,或都指向了同一个对象的下一个地址。
- 一个指针指向某对象,另一个指针指向另外对象的下一个地址。
void * 指针:
void * 是一种特殊的指针类型,可用于存放任意对象的地址。以void * 的视角来看内存空间也仅仅是内存空间,没办法访问内存空间中所存放的对象
需要注意一下几点:
- 指针的类型和它指向的类型必须严格一样,不会进行自动转型。
- int型变量直接赋值给指针式错误的操作,即使是int变量恰好等于0也不行。
指向指针的引用
引用本身不是一个对象,因此不能定义指向引用的指针,但是指针本身是一个对象,可以定义指针的引用:
int i = 42;
int *p;
int *&m = p; //m对指针p的引用
m = &i;
*m = 0;
类型的确定:要理解r到底是什么类型,最直接的方法是从右向左却都r的定义。离变量名最近的符号对变量有直接的影响,&是引用的标志,所以m是一个引用。声明符中其他部分可以确定引用的类型,* 说明引用的是一个指针。
网友评论