Re: [問題] pointer to char位址的問題

作者: LPH66 (-6.2598534e+18f)   2014-08-31 12:42:34
這種底層的問題只好用底層的方式詳細解析一下了...
※ 引述《kdok123 (小天)》之銘言:
: 首先例一:
: int a[] = {1,2,3,4,5};
這一行宣告等同於 int a[5] = {1,2,3,4,5};
不妨設 a 所在的位址是 0x420000
陣列長成這樣:
0x420000 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 ...
[ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] xxxx
: cout << a << endl; //array a 的初始位址
注意到陣列變數在大部份情形下會 decay 成指向首元素的指標
所以這會印出指標 0x420000
: cout << *a << endl; // 1
指向 1 的指標 dereference 所以取得 1
: cout << *(a+1) << endl; // 2
指標 +1 指向下一個元素, 跑到了 0x420004, 所以 dereference 取得 2
: cout << *(*(&a+1)-1) << endl; // 5
這裡就是不會 decay 的情形之一, a 作為一個 int[5] 整個取址
所以 &a 得到指向 0x420000 的 int (*)[5] (指向「長度為 5 的 int 陣列」的指標)
因此 +1 會進一個「長度為 5 的 int 陣列」, 於是指向 0x420014
dereference 得到一個位於 0x420014 的「長度為 5 的 int 陣列」
這時因為後面要 -1 所以它 decay 成指標, 變成指向 0x420014 的 int 指標
-1 後退一個 int, 得到指向 0x420010 的 int 指標
於是 dereference 就會取得 5
: ////////////////以同樣的觀念來看char//////////////
: char a[] = "123";
這裡等同於 char a[4] = {'1', '2', '3', '\0'};
同樣設 a 位於 0x420000
陣列長這樣:
0x420000 01 02 03 04 ...
'1' '2' '3' '\0' xx
: cout << a << endl; // 123 ...式一
這裡 a 成為了一個 char *
而 cout 對 char * 有特殊處理會把它當 C-style 字串印出來
所以就會印出字串 123
: cout << *a << endl; // 1 ...式2
同例一的式 2, dereference 取得 '1'
: cout << *(a+1) << endl; // 2 ...式3
同例一的式 3, dereference 取得 '2' (這次指向 0x420001)
: cout << *(*(&a+1)-1) << endl; // 怪怪的值 .. 式4
照樣進行, &a 得到一個 char (*)[4] (指向「長度為 4 的 char 陣列」的指標)
這個指標指向 0x420000
+1 前進一個「長度為 4 的 char 陣列」, 故指向 0x420004
dereference 取得位於 0x420004 的「長度為 4 的 char 陣列」
後面要 -1 所以 decay 成指向 0x420004 的 char 指標
-1 後退一個 char 指向 0x420003
再 dereference 就會取得 '\0'
至於這個字送給 cout 會怎麼印在螢幕上就不知道了....
: ///////////////以下為問題/////////////////////////
: 從式2和式3可以知道a是一個pointer,但從式一和式四卻不能出現如同例一的效果
: 問題一:我要如何找到a[]的初始位址?(希望可以印出初始位置)
: 問題二:如何實現我要的式4 (希望可以印出3)
: 如果有任何觀念錯誤煩請不吝糾正
: 謝謝
於是這樣看下來你應該是被 char 陣列跟 C-style 字串的雙重身份給搞混了
問題一: 因為 cout 有做上述的特殊處理的關係
你不能直接送一個 char * 進去要他印位址出來
如果你真的要位址的話轉型成 void * 再送進去即可
問題二: "123" 這個 C-style 字串其實是有 4 個元素的
第四個字是 '\0' 用來標記 C-style 字串的結尾
所以例二的式 4 取到了 '\0' 這個字
這樣要怎麼取得 '3' 你應該就知道了...
作者: mabinogi805 (焚離)   2014-08-31 13:07:00
清楚推推
作者: diabloevagto (wi)   2014-08-31 13:09:00
推推
作者: StarRoad (知道越多了解越少)   2014-08-31 13:19:00
作者: user1120 (使用者)   2014-09-01 00:29:00
作者: withfrog () ()   2014-09-01 18:12:00

Links booklink

Contact Us: admin [ a t ] ucptt.com