对于多维数组,我有些困惑。这篇文章最能帮助我理解的问题是这篇文章

Pointer address in a C multidimensional array

我有一个多维数组,初始化如下int zippo[4][2] = {{2, 4}, {6, 8}, {1, 3}, {5, 7}};
当我打印变量zippo*zippo时,它们显示相同的内存地址,但是当我打印**zippo时,它打印2(第一个子数组中的第一个值)。我的问题是,编译器如何知道将zippo取消引用两次以打印第一个数组的第一个值时?例如,为简单起见,如果zippo的内存地址为30,而zippo*zippo的值为15,那么您应该在内存中使用以下表示形式吗?

据我了解,*zippo转到内存位置15来找到该位置的值,恰好恰好是15。所以,不应该再取消引用它一次,导致再次打印15吗?

最佳答案

您认为级别太低。您的问题涉及变量名称和类型(在语言级别)。

声明int zippo[4][2] = {{2, 4}, {6, 8}, {1, 3}, {5, 7}};时,您将得到两个int的四个数组。可以通过多种方式访问​​它们,具体取决于您需要表达的内容。以下是其中涉及的一些子对象:

| 2 | 4 | 6 | 8 | 1 | 3 | 5 | 7 |    The storage for zippo: 8 contiguous ints

|<--+---+---+---+---+---+---+-->|    zippo (the whole array), is an int[4][2]
|<--+-->|                            zippo[0] (also known as *zippo) is an int[2]
                |<--+-->|            zippo[2] is also an int[2]
|<->|                                zippo[0][0] (also known as **zippo) is an int
            |<->|                    zippo[1][1] is also an int

您可以看到这些子对象可以重叠,并且在某些情况下可以共享地址。仍然使它们与对象(对于您,语言和编译器)不同的是它们的类型。

例如,zippo[0]zippo[0][0](这是它的前半部分)具有相同的地址,但是其中一个是int,另一个是两个int的数组。

这就是为什么您不能继续索引zippo[0][0]或尝试在整数计算中使用zippo[0]的原因:即使它们共享相同的存储,它们也是具有不同含义的不同对象。

即使索引到数组涉及指针算术,也没有实际的指针链,也没有您最初了解的int***。都是变量名。

07-24 14:34