指针的指针


内存地址就单纯是个值,若只是单纯想存储内存地址,使用 void* 类型的指针就可以了。

如果需要对指针作运算,那指针需要类型,在〈指针与数组〉最后就看到了,同一个地址,因为指针类型的不同,递增等运算的结果就不同。

那么什么是指针的指针?…呃…还是指针!指针就是存储内存地址,差别在于指针的类型,来看看底下的范例好了:

#include <stdio.h>

int main(void) {
    int n = 10; 
    int *p1 = &n; 
    int **p2 = &p1;

    printf("n 地址:%p\n", p1);
    printf("p1 地址:%p\n", p2);

    return 0;
}

执行结果:

n 地址:0061FEC8
p1 地址:0061FEC4

n存储了 10,n的地址 0x61feb8,指定给p1存储,而p1的地址是0x61feb4,指定给p2存储。

n的类型是int&n获取的值类型是int*,因此指定int*类型的p1,因为指针的定义是type *variable嘛!p1的 type 是int*,自然地,能存储&p1值的变量,就是定义为int* *p,只不过习惯上,定义时会将**排在一起,也才会有方才int **p2 = &p1的写法,若要说p2的类型则是int**

这个简单的范例,只是用来理解想用指针存储另一指针的地址时,类型上是怎么定义罢了,单纯只是用指针来存储另一个指针的地址,没有太大的意义,重点在于指针的类型在运算时扮演的作用,例如〈指针与数组〉中,对变量取址后递增 1,目的是为了要位移一整个数组空间:

int arr[] = {10, 20, 30, 40, 50}; 
int len = *(&arr + 1) - arr;

一维数组变量的元素地址可以储至int*指针,那二维数组呢?在〈二维(多维)数组〉谈过,多维数组是由数组的数组构成,二维数组可以看成数段一维数组构成,必须定义每段一维数组的长度为何:

int arr[2][3] = {{10, 20, 30}, {40, 50, 60}}; 
int (*p)[3] = arr;

三维数组可以看成数段三维数组构成,因此必须定义每段二维数组的宽高为何,例如:

int arr[1][2][3] = {{{10, 20, 30}, {40, 50, 60}}}; 
int (*p)[2][3] = arr;




展开阅读全文