复合类型:引用与指针

51 篇文章 0 订阅
19 篇文章 0 订阅

C++11中新增了一种引用:所谓的“右值引用”,当我们使用术语“引用”时,指的其实是“左值引用”。

引用: 为对象起了另外一个 名字,引用类型引用另外一种类型,通过将声明符写成&d的形式来定义引用类型,其中d是声明的变量名。

int ival = 1024;

int &refVal = ival;

// refVal 指向ival (是ival的另一个名字)

一般在初始化变量时,初始值会被拷贝到新建的对象中。程序把引用和它的初始值绑定在一起,一旦初始化完成,引用将和它的初始值对象一直绑定在一起。因为无法令引用重新绑定到另外一个对象,因此引用必须初始化。

int &refVal2;//报错:引用必须被初始化

refVal = 2;//把2赋給refVal指向的对象,此处即是赋给了ival

int ii = refVal;//与ii =ival执行结果一样

                //正确: refVal3 绑定到了那个与refVal 绑定的对象上,这里就是绑定到ival上

int &refVal3 = refVal;//利用与refVal绑定的对象的值初始化变量i

int i = refVal; //正确: i被初始化为ival的值

因为引用本身不是一一个对象,所以不能定义引用的引用。

 

定义引用允许在一条语句中定义多个引用,其中每个引用标识符都必须以符号&开头。

大部分引用的类型都要和与之绑定的对象严格匹配。而且,引用只能绑定在对象上,而不能与字面值或某个表达式的计算结果绑定在一起。

int  i=1024,i2=2048;//i和i2都是int

int &r=i,r2=i2;//r是一个引用,与i绑定在一起,r2是int

int i3 = 1024, &ri = i3; // i3是int,ri是一个引用,与13绑定在一起

int  &r3=13,&r4=i2;//r3和r4都是引用

 

指针:指针实现了对其他对象的间接访问,指针本身就是一个对象,允许对指针赋值和拷贝,而且在指针的生命周期内它可以先后指向几个不同的对象。指针无须在定义时赋初值。和其他内置类型一样,在块作用域内定义的指针如果没有被初始化,也将拥有一个不确定的值。

 

定义指针:每个变量前面都必须有符号*

int *ip1,*ip2;//ipl和ip2都是指向int型对象的指针

double dp, *dp2; // dp2 是指向double型对象的指针,dp是double型对象

 

获取地址:指针存放某个对象的地址,要想获取该地址,需要使用取址符(&)。指针的类型大多要和它所指向的对象严格匹配。

int *P = &ival; // P存放变量ival的地址,或者说p是指向变量ival的指针



double dval;

double *pd = &dval; // 正确:初始值是double型对象的地址

double *pd2 = pd;//正确:初始值是指向double对象的指针

int *pi = pd;//错误:指针pi的类型和pd的类型不匹配

pi = &dval;//错误:试图把double型对象的地址赋给int型指针

 

指针值

1.指向一个对象。

2.指向紧邻对象所占空间的下一个位置(试图访问此类指针对象的行为不被允许)。

3.空指针,意味着指针没有指向任何对象(试图访问此类指针对象的行为不被允许)。

4.无效指针,也就是上述情况之外的其他值。(试图拷贝或以其他方式访问无效指针的值都将引发错误。编译器并不负责检查此类错误,和使用未经初始化的变量是一样的,访问无效指针的后果无法预计。)

 

访问对象:使用解引用符(操作符*)来访问该对象,对指针解引用会得出所指的对象,因此如果给解引用的结果赋值,实际上也就是给指针所指的对象赋值:

int ival = 42;

int *p = &ival; // p存放着变量ival的地址,或者说p是指向变量ival的指针

cout << *p;//由符号*得到指针p 所指的对象,输出42

*p=0;    //由符号*得到指针p所指的对象,即可经由p为变量ival赋值

cout<<*p;//输出0

 

空指针

生成空指针的方法:

int *p1 = nullptr;//等价于int *pl = 0;

int *p2 = 0;//直接将p2初始化为字面常量0

//需要首先#include cstdlib

int *p3 = NULL;//等价于int*p3=0;

nullptr 种特殊类型的字面值,它可以被转换成任意其他的指针类型,名为NULL的预处理变量。预处理变量不属于命名空间std,它由预处理器负责管理,因此我们可以直接使用预处理变量而无须在前面加上std::。当用到一个预处理变量时,预处理器会自动地将它替换为实际值,因此用NULL初始化指针和用0初始化指针是一样的。在新标准下,现在的C++程序最好使用nullptr,同时尽量避免使用NULL。赋值,这个变量在头文件cstdlib中定义,它的值就是0。

 

把int变量直接赋给指针是错误的操作,即使int变量的值恰好等于0也不行。

int zero = 0;

pi = zero;//错误:不能把int变量直接赋给指针

 

赋值及其他操作: 给指针赋值就是令它存放一个新的地址,从而指向一个新的对象。

int i= 42;

int *pi = 0;// pi 被初始化,但没有指向任何对象

int *pi2 = &i;// pi2被初始化,存有i的地址

pi2 = 0;//现在pi2不指向任何对象了

 

如果指针的值是0,条件取false: 任何非0指针对应的条件值都是true。对于两个类型相同的合法指针,可以用相等操作符(=)或不相等操作符(!=) 来比较它们,如果两个指针存放的地址值相同(都为空、都指向同一个对象, 或者都指向了同一一个对象的下一地址),则它们相等,反之它们不相等。

 

void*指针:void*是一种特殊的指针类型,可用于存放任意对象的地址。不能直接操作void*指针所指的对象,拿它和别的指针比较、作为函数的输入或输出,或者赋给另外一个void*指针。以void*的视角来看内存空间也就仅仅是内存空间,没办法访问内存空间中所存的对象。

double obj = 3.14,*pd = &obj;//正确: void*能存放任意类型对象的地址

void *pv = &obj;// obj 可以是任意类型的对象

 

指向指针的指针:指针是内存中的对象,像其他对象一样也有自己的地址,因此允许把指针的地址再存放到另-一个指针当中。通过*的个数可以区分指针的级别。也就是说,** 表示指向指针的指针,***表示指向指针的指针的指针,以此类推。

int ival = 1024;

int *pi = &ival; // pi指向一个int型的数

int **ppi=&pi;//ppi指向一个int型的指针

 

指向指针的引用

int i= 42;

int *p;// p是一个int型指针

int *&r = p;// r是一个对指针p的引用

复合类型的声明

//主是一个int型的数,p是一个int型指针,r是一个int型引用

inti=1024,*p=&i,&r=i;

int* p1, p2; // p1 是指向int的指针,p2是int

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值