2012-10-12 82 views
1

可能重複:
How are two-dimensional arrays formatted in memory?int ** p的奇怪行爲?

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

誰能告訴我,爲什麼結果是? 如果

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

結果是? (由Visual C++編譯)

+4

檢查http://stackoverflow.com/questions/2565039/how-are-two-dimensional-arrays-formatted-in-memory – devshorts

+0

不是真的準確複製,但得到的答覆是完美的:) – leppie

+2

我想指出這個例子甚至沒有編譯,至少在visual studio 2010中編譯。編譯器給你一個錯誤,告訴你不能將2d數組分配給雙指針。 – devshorts

回答

3

修改方案,H 2 CO 3的答案...

你的第一個DEREF帶你進入陣列1 dimmension。具體而言,它會讓您指向'1'的條目。

這裏大多數人似乎並不完全明白接下來會發生什麼。此時'p'仍被視爲指針。它相信它包含地址'1'。當你做'+1'時,你實際上正在進行指針運算。由於sizeof(int)(通常是)4,因此您只需打印矩陣+4的第一個元素。因此+2轉換爲+8,因爲指針算術總是按照指針指向的'東西'的大小完成的。所以你得到5和9.

快速解除代碼將顯示。

mov eax, DWORD PTR [email protected]@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 
+0

謝謝,指針算術,就是這樣 – xhlwill

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

+0

我原來低估了你,因爲你說他們可以使用簡單的指針線性訪問。這是不正確的。你更新了你的答案,包括他們必須被引用爲數組數組,我刪除了我的downvote。 – devshorts

+0

@devshorts不,這是不正確的。如果將數組的基地址分配給單個指針,則它將起作用。你試圖得到那個工作,但你只想到數組而不是指針。並且「必須將它們作爲數組的數組引用」甚至不在我的答案中。 – 2012-10-12 18:16:22

+0

這並不是答案,而是那個時候你的例子有效地做了什麼。 – devshorts