|
0鱼币
int arr [2][5] = {{1,2,3,4,5},{6,7,8,9,10}};
arr == 二维数组的开始地址;
arr+1 == arr[1]的地址;
为什么 *arr 还是等于二维数组的开始地址呢?不因该是arr[0][0]里面存放的值吗?
*(arr + 1) 也不是应该指向的时arr[1][0]里面存放的值吗?为什么显示的还是arr[1][0]的地址呢?
为什么要用两个解引用才能够获取里面的值呢?
**(arr + 1) == 6;
本帖最后由 fc1735 于 2016-11-26 17:50 编辑
那是写给编译器看的,没有特别的理由,但它的运作方式是符合逻辑的。
已知a[5]等价于*(a+5)
如果你要让arr[1][4]等价于 *( *(arr+1) +4)的时候,上述你说的情况是必然的。
首先 arr+1的加1跨度必须是5个int,可是我们没有这种类型,喔!那就把arr当成指向int[5]类型吧。
那解引用呢? *(arr+1)根据指针的逻辑已经是int[5]类型的,那int [5]类型+4是什么意思呢?取值的时候只需要4个byte,对一个20byte的类型取值又是什么意思,这显然不能满足我们的要求
那就把指向int [5]的解引用当成脱一层壳变成指向int 类型的好了,取代了原本的把值当作地址再取值,然后地址不变,就只是脱一层壳,这样的定义就满足了所有n维数组
转换成汇编后,完全看不到上述的假象
简单来说 ,只要理解为指向数组的解引用就是脱一层壳就好。
比如int a[1][2][3][4][5][6][7][8][9] 中的a 的类型是指向int[2][3][4][5] [6][7][8][9]的
表示a的地址有很多种方式,
&a == a == *a == **a == ***a == ****a == *****a == ******a....... ...
在底层都是同个东西,但在形式上是不同的,每取值一次就是脱一层壳,虽然值没变,但跨度变了,总层数也下降一个,当到最后一层时就是你想要的元素的值了
换个方式说
你用int* b =上述n种等价表示法后
取*b都是a[0][0][0][0][0][0][0][0][0],只会跑出警告说类型不符而已,因为是同个东西,只是形式上、意义上不同,
|
|