int ** p的奇怪行为?

时间:2012-10-12 17:28:05

标签: c visual-c++

  

可能重复:
  How are two-dimensional arrays formatted in memory?

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 ++编译)

2 个答案:

答案 0 :(得分: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);

不符合您的想法。这是未定义的行为,因为*p的类型是int *,但%d格式说明符需要int。基本上,不要试图将数组视为指针,因为它们不一样。请阅读relevant part of the C FAQ以了解如何正确处理这种情况。基本上,在这种情况下使用一维指针并正确索引就足够了。

演示:

enter image description here

答案 1 :(得分:3)

修改为H2C03的答案......

你的第一个deref带你进入数组1的dimmension。具体来说,它会让您指向“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