C/C++数组与指针dereference问题
见下图代码,注释表示问题,输出结果在最后:
int b[2][3]= {1,2,3,4,5,6}; cout<<b<<endl;
cout<<*b<<endl;
cout<<&b<<endl;
cout<<b[0]<<endl;
cout<<&b[0]<<endl;
cout<<*b[0]<<endl;//1.既然b[0]和b地址是一样的,为什么取value得到的结果不同,换言之为什么*b取到的仍然是地址?
cout<<"---------"<<endl;
cout<<(b+1)<<endl; cout<<*(b+1)<<endl; // 2.此行和上一行输出结果一样,那下一行代码加*的作用是什么?
cout<<(*(b+1)+2)<<endl;
cout<<(b[1]+2)<<endl;
cout<<"---------"<<endl;
cout<<&b[0][5]<<endl; cout<<&b[1][2]<<endl;
cout<<(b[0]+5)<<endl;
cout<<(b+5)<<endl; //3.2D->1D,为什么得到的不是第六个元素的地址呢?
Output:
PS:本人有强迫症囧...学数据结构的时候发现自己C/C++没学好...可是这样补基础是不是有点钻牛角尖啊...恳请有经验的人指导下...
回答:
指针算术运算和数组下标访问是等价的。C的多维数组在内存中是连续的线性结构。
- b的类型在下标访问时会变换为指向长度为三的数组的指针(
int (*b)[3];
),所以*b的类型是长度为三的数组。 - b+1代表这个二维数组的第二行,此时该表达式的类型还是指向数组的指针。(b+1)跟*(b+1)的区别仅仅在于多“剥”了一层指针。两者指代内存中的位置是一样的,就好比cout下&b[0]和&b[0][0]输出相同。
- b+5访问的是b[5][0]。0x22440c + 5*3*4 = 0x22ff34。
回答:
本质上来说c/c++没有多维的数组,全部是由一位数组实现的。区别一维和多维数组仅仅在数组的类型上,如int *
和int **
虽然b
和b[0]
地址相同,但是他们的类型不同,分别是int **
和int *
,所以解引用后的类型当然也不同。也就是说b
和b[0]
都是同一个指针,本质上都是一维指针,但是可以通过类型区别是逻辑上的以为指针还是二维指针。
回答:
c/c++中,数组(原生数组)都是线性结构的,并且其名字可以当做低一维数组的指针使用。
比如说一维数组int a[n]
的名字a
,可以当成int *
(的右值)来使用,等同于&a[0]
。实际上,你在使用的时候,指针运算都被当做指针,只有少数情况,比如声明和sizeof的时候,才被看做数组。
二维数组int b[m][n]
的b
,可以当成int (*)[n]
,同理它等同于&b[0]
。当你对它取了下标,比如b[0]
之后,它就变成int [n]
了,这个时候可以当成int *
使用。这里面是两个步骤,并不是一开始就能当做int **
。
至于&b
,&b[0]
和&b[0][0]
,分别表示整个数组的首地址,数组第一行的首地址,和数组首个元素的地址,他们的值是一样的。但是类型不同,分别为int (*)[m][n]
,int (*)[n]
,和int *
。
以上是 C/C++数组与指针dereference问题 的全部内容, 来源链接: utcz.com/p/191466.html