鱼C论坛

 找回密码
 立即注册
查看: 1801|回复: 11

[已解决]二维数组和指针

[复制链接]
发表于 2016-11-26 13:37:12 | 显示全部楼层 |阅读模式
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;
最佳答案
2016-11-26 13:37:13
本帖最后由 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],只会跑出警告说类型不符而已,因为是同个东西,只是形式上、意义上不同,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-11-26 13:37:13 | 显示全部楼层    本楼为最佳答案   
本帖最后由 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],只会跑出警告说类型不符而已,因为是同个东西,只是形式上、意义上不同,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-11-26 14:15:28 | 显示全部楼层
指针的指针,*arr 表示arr[0]的地址,*(arr + 1) 表示arr[1] ,
*(arr + 1) 先(arr + 1)得到的是arr的一个偏移量,指向的是arr[1]整个数组

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2016-11-26 17:31:25 | 显示全部楼层
fc1735 发表于 2016-11-26 16:31
那是写给编译器看的,没有特别的理由,但它的运作方式是符合逻辑的。

已知a[5]等价于*(a+5)

兄弟,还是不明白!!!!!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-11-26 17:52:38 | 显示全部楼层
本帖最后由 fc1735 于 2016-11-26 18:28 编辑
qq1242009750 发表于 2016-11-26 17:31
兄弟,还是不明白!!!!!!!


我用编辑的回覆你
在上面的帖子中喔
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2016-11-26 18:14:11 | 显示全部楼层
fc1735 发表于 2016-11-26 17:52
我用编辑的回覆你

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2016-11-26 19:32:39 | 显示全部楼层
fc1735 发表于 2016-11-26 16:31
那是写给编译器看的,没有特别的理由,但它的运作方式是符合逻辑的。

已知a[5]等价于*(a+5)

兄弟   


int arr[2][3]

*arr;//这里就降了一个唯独 从二维变到了一维

例如 int arr1[2][3][4]

我要取 arr[1][2][1]的值  

*(*(*(arr) + 2) + 1)

*(arr ) 表示把三维降级到二维


*(*arr)+2 表示把二维变为一维

*(*(*(arr) + 2)+ 1) 表示把一位解引用为 arr[1][2][1]的值


这样对吗???
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2016-11-26 19:34:17 | 显示全部楼层
DarkSE 发表于 2016-11-26 14:15
指针的指针,*arr 表示arr[0]的地址,*(arr + 1) 表示arr[1] ,
*(arr + 1) 先(arr + 1)得到的是arr的一 ...

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2016-11-26 19:34:48 | 显示全部楼层
谢谢 大家的帮助 现在明白了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-11-26 19:35:53 | 显示全部楼层
本帖最后由 fc1735 于 2016-11-26 19:37 编辑


基本上你说的是对的,但不应该问我对不对,应该自己编程测试一下,因为C语言不是我写出来的

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2016-11-26 20:39:51 | 显示全部楼层
fc1735 发表于 2016-11-26 19:35
基本上你说的是对的,但不应该问我对不对,应该自己编程测试一下,因为C语言不是我写出来的
...

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-11-26 21:34:17 | 显示全部楼层
好热闹,凑热闹
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-25 21:13

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表