作者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