书上说二维数组在内存中实际是以一维数组的形式连续存放的,我做了个小测试结果却令我无法理解。
#include <iostream>
using namespace std;
int main() {
int a[2][2] = {{0,1},{2,3}};
cout << &a << endl;
cout << a << endl;
cout << *a << endl;
cout << a[0] << endl;
cout << **a << endl;
cout << *(a[0]) << endl;
return 0;
}
输出:
0x7fff396c0210
0x7fff396c0210
0x7fff396c0210
0x7fff396c0210
0
0
那个内存地址处保存的是自己的地址?那么两次解引用不应该还是这个地址才对吗?怎么会变成0???
黄舟2017-04-17 15:39:18
你應該這樣理解,在C裡面只有一維數組,只不過數組的元素可以是任意型,包括數組本身,所以才有二維數組。這樣的話,對一個數組名解引用(這時候數組名就是指向該數組第一個元素的指標)得到的就是該數組的第一個元素,而二維數組的第一個元素是一個一維數組,所以再次解引用就是這個一維數組的第一個元素。就跟你下面那個*(a[0])是一樣的。
對於你說的這個問題,數組a這個名字就是指向a這個數組內容的指針,他的值和他第一個元素的地址是一樣的。對於二維數組來說,a,a[0]的地址,a0的地址這三個值是一樣的,但是含義略有不同,a和a[0]的地址具有相同含義,是一個二級指針,但a0的位址卻是一級指標
PHPz2017-04-17 15:39:18
斷點調試下監視下如下內容:
a
&a
a+0
a[0]
&a[0]
對於上述問題,首先知道三點:
(1)二維數組就是一維數組
這個很好證明,依次輸出地址,都是連續的,不多說。
(2)陣列位址是什麼?
先從一維陣列開始int b[2]
,陣列位址就是對一個陣列名稱進行取址,例如&b就是陣列位址。
二維的int a[2][2]
,a是二維數組名,&a就是二維數組位址;a[0]是第一行的數組名(姑且叫第一行),&a[0]是第一行數組的數組位址,同理a[1],&a[1]分別是第二行數組名和數組地址。
(3)陣列名稱可以轉換成指針
先修正一點int b[2]
,這裡的b不是指針,同樣的,int a[2][2]
,裡邊的a也不是指針,但是a和b可以轉換成指針,可以轉換不代表它就是,誰告訴你int就是short了。
好了,要理解你的程式碼為什麼這樣,最好的辦法直接監視類型即可。
注意看a[0]與b的種類。