作者ric2k1 (Ric)
看板EE_DSnP
標題Re: [問題] 有關指標的問題
時間Thu Oct 7 01:39:01 2010
感謝 rm2 大大的回答,基本上是回答得差不多了,
我這裡就用一個更簡單的例子來說明一下:
其實你的問題在一維陣列就會發生,比方說下面這個程式:
int main()
{
int a[10] = { 0 };
cout << a << endl;
cout << &a << endl;
cout << &a[0] << endl;
int *p = new int[10];
cout << p << endl;
cout << &p << endl;
cout << &p[0] << endl;
}
在我的電腦輸出是:
0x7fff0a912bd0
0x7fff0a912bd0
0x7fff0a912bd0
0x13d3e010
0x7fff0a912bf8
0x13d3e010
我先從下半部說明起:
首先,如我上課一直在強調的,
請將 "int *p = ..." 的 p 當作是一個 local variable,
也就是說它會被存在 stack memory,
而它的內容就是 "new int[10]" 所 return 回來的位置。
另外,p[0] 就如同 *p,就是 p 所指到的那塊記憶體的第一個 int。
所以:
1. "cout << p" 是印出 p 的 "內容",也就是 "new int[10]" 的記憶體位置。
2. "cout << &p" 是印出存 p 這個 local variable 的位置,
所以印出來的很明顯的是一個 stack memory 的位置。
3. "cout << &p[0]" 是印出存 p[0] 這個 int 的位置,
很明顯的 p[0] 就是 heap memory 中 "new int[10]" 的第一個 int,
所以印出來就是 "new int[10]" 的記憶體位置,也就是跟 p 的內容一樣。
我們接下來來看
int a[10] = { 0 };
cout << a << endl;
cout << &a << endl;
cout << &a[0] << endl;
請注意 a[10] 整體是個 local varialbe, 也就是整個是存在 stack memory 裡面的,
與 "int *p = new int[10]" 不一樣的是,並沒有像 p 那樣有另一個 local variable
來存 "new int[10]" 的位置。
也就是說並沒有一個獨立的記憶體位置來存 "a",
因為 a "概念上" 就是一個指到 "a[0]" 的指標,因為 *a 與 a[0] 同義。
所以嚴格來說 &a 並沒有意義,因為我說過,"a" 並不是一個獨立於 a[10] 的變數,
但是因為我們允許 "cout << a" (i.e. 讀取 "a 這個變數" 的內容),
所以 "勉為其難" (好啦,這是我說的) 將 &a 定義成與 a 一樣。
所以:
1. "cout << a" 會印出 "a 的內容",也就是 a[10] 這整個區塊開頭的記憶體位置。
很明顯的,它是在 stack memeory 裏。
2. "cout << &a",如上所述,請將 &a 視為 a,所以結果會跟 1 一樣。
3. "cout << &a[0]" 會印出 "a[0] 所存放的位置",其實就跟 "a[10]" 的位置一樣,
結論是三者印出的都一樣。
至於二維或是更多維的變數,其實我覺得概念是一樣的。
比方說 "int a[3][5]",
你可以想像成 "int[5] a[3]",
也就是大小是 3 的陣列,其中每個元素是一個大小是 5 的 int array。
依此類推,希望你能了解?
※ 引述《BBSealion (海獅)》之銘言:
: 以前就有個問題沒有想清楚
: 剛好今天老師上到,po在這請教大家一下
: ---
: 今天宣告一個雙層array :int arr[3][5] = {10,20,30, .......}
: 以下四行指令,竟然會顯示相同的結果?
: cout << &arr[0][0];
: cout << &arr[0];
: cout << arr[0];
: cout << arr;
: 都一樣顯示出一個位址(在我家是 0x22ff10)
: 感覺實在挺沒道理的
: (1=3,2=4還算合理,但全部相同就是不太舒服orz)
: 也就是說arr = 0x22ff10 是一個位址
: 但用*取arr的值的話(*arr)還是會出現同樣的東西(地址) *arr = arr = 0x22ff10
: 再取一次(**arr)才會給你arr[0][0]的值(ex:10)
: 這樣不會有記憶體位址打架的問題嗎!?
: 同樣對0x22ff10這個位址,用*取值,一次還是給我0x22ff10,一次卻給我該位址的值
: ---
: ps:改用動態宣告問題就解決了
: (給另任意p,q)
: int **c = new int*[p];
: for (int i=0;i<p;i++){
: c[i] = new int[q];
: for (int j=0;j<q;j++){
: *(c[i]+j) = 100*i+j*j;
: }
: }
: 以下四行指令
: cout << &c[0][0] ;
: cout << &c[0] ;
: cout << c[0] ;
: cout << c ;
: 第一行結果=第三行結果=0x2e24a0
: 第二行結果=第四行結果=0x2e2470
:
: ---
: 請問有人能解釋一下直接宣告雙層array發生的問題嗎QQ?
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 123.193.11.13
1F:→ ric2k1:我想到這個問題以前在教計程好像有討論過,但是那頁 slide 10/07 01:40
2F:→ ric2k1:在 DSnP 被省略掉了... 10/07 01:40
3F:推 x8318:老師真晚睡,保重龍體啊!! 10/07 02:00
4F:推 BBSealion:感謝! 我研究看看 10/07 22:35