2.形形色色的指针
All Kinds of Pointers
前一章我们引入了指针及其定义,这一节我们继续研究各种不同的指针及其定义方式(注:由于函数指针较为特殊,本章暂不作讨论,但凡出现“指针”一词,如非特别说明均指数据指针)。
1)指向指针的指针
我们已经知道,指针变量是用于储存特定数据类型地址的变量,假如我们定义
int *pInt;
那么,pInt为一个指向整型变量的指针变量。好,我们把前面这句话的主干提取出来,就是:pInt为变量。既然pInt是变量,在内存中就会有与之对应的存放数据的地址值,那么理论上也就应该有对应的指针来存储,嗯,实际上也如此,我们可以向这样来定义可以指向变量pInt的指针:
int **pIntPtr;
按前一章的方法很好理解这样的定义:**pIntPtr是一个int类型,则去掉一个*,*pIntPtr就是指向int的指针,再去一个*,我们最终得到的pIntPtr就是一个“指向int型指针变量的指针变量”,呵呵,是点拗口,不管怎么说我们现在可以写:
pIntPtr = &pInt;
令其指向pInt变量,而*pIntPtr则可以得回pInt变量。假如pInt指向某个整型变量如a,*pInt可以代表a,因此*(*pIntPtr)此时也可以更间接地得到a,当然我们如果省去括号,写成**pIntPtr也是可以的。
以此类推,我们还可以得到int ***p这样的“指向指向指向int型变量的指针的指针的指针”,或者再复杂:int ****p,“指向指向指向指向……”喔,说起来已经很晕了,不过原理摆在这里,自己类比一下即可。
2)指针与常量
C++的常量可以分两种,一种是“文本”常量,比如我们程序中出现的18,3.14,’a’等等;另一种则是用关键字const定义的常量。大多数时候可以把这两种常量视为等同,但还是有一些细微差别,例如,“文本”常量不可直接用&寻找其在内存中对应的地址,但const定义的常量则可以。也就是说,我们不能写&18这样的表达式,但假如我们定义了
const int ClassNumber = 18;
则我们可以通过&ClassNumber表达式得到常量ClassNumber的地址(不是常数18的地址!)。其实在存储特点上常量与变量基本是一样的(有对应的地址,并且在对应地址上存有相应的值),我们可以把常量看作一种“受限”的变量:只可读不可写。既然它们如此相似,而变量有对应的指针,那么常量也应该有其对应的指针。比如,一个指向int型常量的指针pConstInt定义如下:
const int *pConstInt;
它意味着*pConstInt是一个整型常量,因此pConstInt就是一个指向整型常量的指针。我们就可以写
pConstInt = &ClassNumber;
来令pConstInt指向常量ClassNumber. 给你三秒钟,请判断pConstInt是常量还是变量。1,2