在C中,当我们使用指针访问a[i][j]
时,为什么我们需要*
中的第二个*(*(a + i) + j)
?使用printf()
我看到a + i
和*(a + i)
打印相同的值。
答案 0 :(得分:9)
a + i
是指向i
'子阵列的指针。如果你取消引用它,你得到i
'子数组的左值,它会衰减到指向该数组的第一个元素的指针。数组的第一个元素的地址和它的数组的地址是相同的。
需要取消引用以使用正确的元素字节宽度计算+ j
。如果您不取消引用,那么您将获得一个T*
指针,而不是获取T(*)[J]
,而是j
指针,它与i
一起前进到指向{{{1}的内存中1}}代替(按(a + i + j)
而不是sizeof(T[J])
推进)。
答案 1 :(得分:1)
好的,这需要一点指针理论。
让我们假设我们有
int** a = malloc(sizeof(int*) * 10);
int** p;
for(p = a; p < a + 10; p++) {
*p = malloc(sizeof(int) * 15);
}
这创建了一个使用指针实现的10乘15“数组”。请注意a
指向的内存块中包含的每个元素的类型是int*
(因为我们正在对15 int
s的块进行malloc。
这是一张不完整的图表:
a
|
1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 8 - 9 - 10
| |
| 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15
|
1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15
因此主指针是指向包含一堆指针的块的指针。因此,您最终取消引用以获取内部指针,添加以获取另一个指针,然后再次取消引用。
答案 2 :(得分:0)
2D数组就像数组一样。 *(a + i)为您提供起始地址位于i的一维数组的地址。现在您需要此数组中位置j的元素。因此,你添加j&amp;然后使用*取消引用以访问该元素。