光标题就够让人胆怯的了,又是指针?还指向指针?还指向数组?
要弄清这个问题,还得从指针的本质说起。
每次提到指针,我总是要反复提起“指针也是一个变量”,当你对指针本身进行操作时,就是对一个变量进行操作。指针唯一的特点是:它的值是一个内存地址,通过它可以间接寻找到其它变量(或常量)。
如果光通过它寻找其它变量常量,那倒也不必这么复杂。关键是,找来的数据要进行处理的话,必须知道那个数据的类型。大家都知道int和long是不一样的,那么,指向这两种类型变量的指针,它们的区别在哪儿呢?
应该说,在本质上它们没有区别,它们都是指向内存地址。内存除了地址区别以外,没有其它区别。同一个内存地址,可以放int,可以放long,还可以放char。为了保证对每一个变量的操作都符合要求,C++惟一的对策就是在声明指针的时候就规定了这个指针所指的类型。如“int *p”,int只是表示了p所指对象的类型,而不表示p的类型。
C++这样做还有另一个好处,就是方便直观地移动指针。对于加、减运算来说,许多人都早已烂熟于心,但是对于指针的加减运算,于其说加减,还不如说前移和后移。++p就是让p指向后面一个对象。至于p的值究竟加了多少?这可不一定。这要看p指向的对象占内存大小了。
更直观地说,如果p是指向char的,那么++p就是让p的值增1,如果p是指向long的,可就是增4了(某些系统用8字节表示long,那就增8)。
下面该提到“指向指针的指针”了,对于int **p来说,p所指的对象是指针,那么++p就是让p的值增一个指针的大小,虽然指针所指对像可大可小,但是指针自己的大小却是一定的,目前的系统上一般是4字节(64位系统我没用过,可能是8字节)。也就是说,对char *p和long *q来说,p和q本身占内存容量是一样大的(虽然char和long占内存不一样大)。
很多人以为“指向数组的指针”就是“指向指针的指针”,于是有人写这样的代码:
int a[3][4];
int **p = a;//错误
这个代码的错误之处在于a是一个数组,它的成员也是数组,所以a叫做“数组的数组”——C++中严格说来没有二维数组。那么,你要用一个指针来记录a,就要用一个能表示“数组的数组”的指针,以下代码是正确的:
int (*p)[4] = a;//正确
只有这样才能保证++p使p指向a的下一对像(该对像是一个数组)。
顺便提一句:不要写成“int *p[4];”
本站文章皆为作者原创,其它媒体(包括但不限于报刊、杂志、网站、电视、电台)未经作者书面许可严禁转载(或部分摘录)!
