C语言中指针的指针是如何工作的?
我们有时看到这样地饿代码:
int *ptr = &x;
这里,ptr是一个指向x在内存中的地址的指针。
假设有另外一条语句是这样地的:
int **ptr2 = &ptr;
我们定义了一个指向指针的指针。
假设我们的计算机是8bit的,地址也是8bit(因此只有256字节的内存)。下图代表内存的一部分(上面的一排数字代表地址)。
45 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
| | 58 | | | 63 | | 55 | | | h | e | l | l | o | \0 | |
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
从上面可以看到地址63是字符串“hello”开始的地方。这种情况,假设内存中只有一处出现了“hello”,那么:
const char *c = "hello";
定义c为指向字符串“hello”的指针,那么c里面的值是63。指针c自己也要存储在内存的某个地方,上面的例子中可以看到c存储在58的位置。既然我们能定义指向字符的指针,也就能定义指向指针的指针:
const char **cp = &c;
现在cp指向了c,cp中存储的是c的地址(58)。
甚至可以更进一步:
const char ***cpp = &cp;
cpp内存的是cp的地址,也就是55(在上面的例子中),cpp自身存储在60的位置。
为什么我们需要这些指针呢?
- 数组名通常也是数组第一个元素的地址。如果数组中存储的数据类型是t,对数组引用的类型就是* t。假设有类型t的数组的数组(二维数组),自然地,对二维数组的引用类型就是*(*t)=**t,也即指向指针的指针。
- 即使字符串的数组看起来像是一维的,事实上是二维的,因为字符串时字符的数组。因此,类型为char **。
Copyright © 2015 programnote