变量3

理解复合类型的声明

变量的定义包括一个基本数据类型和一组声明符。在同一条定义语句中,虽然基本数据类型只有一个,但是声明符的形式却可以不同。也就是说,一条定义语句可能定义出不同类型的变量:
//i是一个int型的数, p是一个int型指针, r是一个int型引用
int i= 1024, *p = &i, &r = i;
warning:很多程序员容易迷惑于基本数据类型和类型修饰符的关系,其实后者不过是声明符的一部分罢了。

定义多个变量

经常有一种观点会误以为,在定义语句中,类型修饰符(*或&)作用于本次定义的全部变量。造成这种错误的原因有很多,其中之一是我们可以把空格写在类型修饰符和变量名中间:

int* p;		//合法但是容易产生误导

我们说这种写法可能产生误导是因为int *放在一起好像是这条语句中所有变量共同的类型一样。其实恰恰相反,基本数据类型是int而非 int *。*仅仅是修饰了p而已,对该声明语句中的其他变量,它并不产生任何作用:

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

涉及指针或引用的声明,一般有两种写法。第一种把修饰符和变量标识符写在一起:

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

这种形式着重强调变量具有的复合类型。第二种把修饰符和类型名写在一起,并且每条语句只定义一个变量:

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

这种形式着重强调本次声明定义了一种复合类型。

指向指针的指针

一般来说,声明符中修饰符的个数并没有限制。当有多个修饰符连写在一起时,按照其逻辑关系详加解释即可。以指针为例,指针是内存中的对象,像其他对象一样也有自己的地址,因此允许指针的地址再存放到另一个指针当中。
通过的个数可以区分指针的级别。也就是说, * *表示指向指针的指针,***表示指向指针的指针的指针,以此类推:

int ival = 1024;
int *pi = &ival;	//pi指向一个int型的数
int  **ppi = π		//ppi指向一个int型的指针

此处pi是指向int型数的指针,而ppi是指向int型指针的指针,下图描述了它们之间的关系。

解引用int型指针会得到一个int型的数,同样,解引用指向指针的指针会得到一个指针。此时为了访问最原始的那个对象,需要对指针的指针做两次解引用:

cout << "The value of ival\n"
		<< "direct value: " <<ival << "\n"
		<< "indirect value: " << *pi << "\n"
		<< "doubly indirect value: " << **ppi
		<< endl;

该程序使用三种不同的方式输出变量ival的值:
1.直接输出
2.通过int型指针pi输出
3.两次解引用ppi,取得ival的值

指向指针的引用

==引用本身不是一个对象,因此不能定义指向引用的指针。==但是指针是对象,所以存在对指针的引用:

int i = 32;
int *p;	//p是一个int型指针
int *&r = p;	//r是一个对指针p的引用
r = &i;		//r引用了一个指针,因此给r赋值&i就是令p指向i
*r = 0;	//解引用r得到i,也就是p指向的对象,将i的值改为0

要理解r的类型到底是什么,最简单的办法是从右向左阅读r的定义。离变量名最近的符号(此例中&r的符号&)对变量的类型有最直接的影响,因此r是一个引用。声明符的其余部分可以确定r引用的类型是什么,此例中的符号*说明r引用的是一个指针。最后,声明的基本数据类型部分指出r引用的是一个int指针。
Tip:面对一条比较复杂的指针或引用的声明语句时,从右向左阅读有助于弄清楚它的真实含义。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值