2.3复合类型

复合类型(compound type)是指基于其他类型定义的类型。C++语言有几种复合类型。

本章介绍:引用和指针

普通声明:

基本数据类型(base type) + 声明符(declarator)

2.3.1 引用

 

Note: 严格来说使用术语“引用(reference)”时,指的是“左值引用(lvalue reference)”

 

引用为对象起了另外一个名字,引用类型引用另外一种类型。

通过将声明符写成&d的形式来定义引用类型,其中d是声明的变量名

 int ival = 1024;

 int &refVal = ival; //refVal 指向ival (是ival的另一个名字)

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

一般初始化变量时,初始值会被拷贝到新建的对象中。定义引用时,程序把引用和它的初始值绑定(bind)在一起,无法令引用重新绑定到另外一个对象,引用必须初始化。

 

引用即别命名

Note:引用并非对象,相反的,它只是为一个已存在的对象所起的另外一个名字。

定义了一个引用后,对其进行的所有操作都是在与之绑定的对象上进行的

为引用赋值实际上是赋值给了与引用绑定的对象

引用本身不是一个对象

不可定义引用的引用

引用的定义

引用类型初始值一定是个对象

引用类型的初始值和引用类型一致

 

2.3.2 指针(重要!!!)

 

指针(pointer)是指向另一种类型的复合类型。

与引用类似,指针也实现了对其他对象的间接访问。

与引用不同,

其一,指针本身就是一个对象,允许对指针复制和拷贝,指针生命周期内它可以先后指向几个不同的对象。

其二,指针无需在定义时赋初始值。和其他内置类型一样,在块作用域内定义的指针如果没有被初始化,也将拥有一个不确定值。

 

定义指针类型的方法将声明符写成*d的形式

获取对象的地址

 

指针存放某个对象的地址,要想获取该地址,需要使用 取地址符(操作符&)

 int *p = &ival

//p存放变量ival的地址,或者说p是指向变量ival的指针

 

除p56和p534要介绍的两种例外情况,其他的所有指针的类型都要和它所指向的对象严格匹配。

 double dval;

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

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

 

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

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

 

指针值

  指针的值(即地址)应该属于下列4种状态之一;

1.指向一个对象

2.指向紧邻对象所占空间的下一个位置

3.空指针,意味着指针没有指向任何对象

4.无效指针,也就是上述情况外的其他值

 

 

试图拷贝或以其他方法访问无效指针的值都将引发错误

 

2,3情况的指针有效但是不允许访问

 

利用指针访问对象

  如果指针指向了一个对象,则允许使用 解引用符(操作符*)来访问该对象

 

 int ival =42;

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

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

 

 

Note: 解引用操作仅适用于那些确实指向了某个对象的有效指针

 

 

关键概念:某些符号有多重含义

 int i = 42;                    

 int &r = i;                &紧随类型名出现,因此是声明的一部分,r是一个引用

 int  *p;                     *紧随变量名出现,因此是声明的一部分,p是一个指针

 p =  &i;                    &出现在表达式中,是一个取地址符

 *p = i;                      *出现在表达式中,是一个解引用符

 int &r2 = *p              &是声明的一部分,*是一个解引用符

 

 

空指针

 空指针(null pointer)不指向任何对象

生成空指针方法:

  1.  int *p1 = nullptr;
  2.  int *p2 = 0 ;
  3.  int *p3 =NULL; //需要#include cstdlib ,定义在cstdlib中的名为NULL的预处理变量

 

建议:初始化所有指针

 

赋值和指针

赋值改变的是等号左侧的对象

 pi = &ival; //pi的值被改变,现在pi指向了ival

 *pi =0; //ival的值被改变,指针pi没有发生改变

其他指针操作

指针拥有合法的值

指针的值是0则返回false,其他情况返回true

 

可以用操作符(==    !=)比较两个指针,如果指针存放地址相同,则它们相等。

相等有三种情况:

都为空

都指向同一个对象

都指向同一个对象的下一地址

一个指针指向某对象,另一个指针只想另外对象的下一地址可有可能

 

 

 void*指针

 void*是特殊的指针类型,可以用于存放任意对象的地址,任意类型指针

不能操作void*指针所指的对象,因为不知道这个对象是什么类型

 

2.3.3 理解复合类型的声明

定义多个变量

 略

 

指向指针的指针

指针式内存中的对象,像其他对象一样也有自己的地址,因此允许把指针的地址再存放到另一个指针中。

通过*的个数可以区分指针的级别,**是指向指针的指针

 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的引用

 r =&I;                 //r引用了一个指针,因此给r赋值就是令p指向I

 *r =0                   //将i的值改为0

TIPS: 面对一条比较复杂的指针或引用的声明语句时,从 右向左读

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值