1

可能重复:
二维数组如何在内存中格式化?

int map[3][3] = {1,2,3,4,5,6,7,8,9};
int **p = map;
printf( "%d", *p+1 );

有人能告诉我为什么结果是5吗?而如果

printf( "%d", *p+2);

结果是9?(由 Visual C++ 编译)

4

2 回答 2

3

因为数组不是指针。双指针不等同于二维数组,因为数组在内存中是连续的。您的数组已创建并填充数据,如下所示:

map[0][0] = 1
map[0][1] = 2
map[0][2] = 3
map[1][0] = 4
map[1][1] = 5
map[1][2] = 6
map[2][0] = 7
map[2][1] = 8
map[2][2] = 9

当您将其分配给双指针时,您做错了几件事。例如:

printf("%d", *p + 1);

不做你认为它做的事。这是未定义的行为,因为*pis的类型int *%d格式说明符需要int. 基本上,不要试图将数组视为指针,因为它们不一样。请阅读C FAQ 的相关部分,以了解如何正确处理这种情况。基本上,在这种情况下使用一维指针并正确索引就足够了。

示范:

在此处输入图像描述

于 2012-10-12T17:36:41.190 回答
3

要修改 H2C03 的答案...

您的第一个 deref 会将您带入数组 1 维度。具体来说,它让您指向“1”的条目。

这里的大多数人似乎并没有完全弄清楚接下来会发生什么。此时' p'仍然被认为是一个指针。它认为它包含地址“1”。当您执行“+1”时,您实际上得到的是指针算术。由于 sizeof(int ) (通常)为 4,因此您只需打印矩阵 +4 的第一个元素。因此 +2 转换为 +8 因为指针运算总是根据指针指向的“事物”的大小来完成。所以你得到 5 和 9。

将显示代码的快速解除。

mov eax, DWORD PTR ?p@@3PAPAHA      ; p
mov ecx, DWORD PTR [eax]            ; deref of p (which is '1')
add ecx, 4                          ; let's just +4 it and push it as the arg to printf
push    ecx
push    OFFSET $SG3670
call    _printf
于 2012-10-12T17:45:12.073 回答