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