鱼C论坛

 找回密码
 立即注册
查看: 1955|回复: 13

二维数组与指针的关系

[复制链接]
发表于 2014-2-25 17:53:41 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. #include <stdio.h>
  2. int main()
  3. {   
  4.     int a[3][4]={{4,3,1,5},{1,2,3,4},{0,9,5,7}};
  5.     int b[4]={2,4,5,6};
  6.     printf("%d %d %d\n",b+1,&b[1],*b);
  7.     printf("%d %d %d %d %d %d",&a,a,*a,a[0],&a[0],a[0][0]);
  8.     while(1);
  9.     return 0;
  10. }
复制代码
u=442585331,2501655269&fm=23&gp=0.jpg Q:
1.把二维数组看成是数组的数组,那么a指向的是a[0],a[0]指向的是a[0][0]的地址,可是为啥a,a[0],a[0][0]的地址相同,可是对他们取*操作结果却不一样,编译器内部是怎么处理的?

2.我在一个帖子里头看见这句话”int (*)[4] :可以看做是个二维数组,这里的(*)也代表了一维,后面[4]又是一维。“,不知道这句话是对还是错,如果对的话如何理解,为啥(*)也代表一维?是不是因为指向一维数组的指针算作二维(级)?
是不是指向一维数组的指针取*后退化成指向一个基本类型的指针,所以*运算不只是取内存单元中的值那么简单?
有点乱。。。。

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

使用道具 举报

发表于 2014-2-25 18:24:28 | 显示全部楼层

回帖奖励 +5 鱼币

看看,,,,,,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-2-25 18:45:50 | 显示全部楼层
如果你能看懂汇编的话。。
  1.         .section        .rodata
  2. .LC0:
  3.         .string        "%d %d %d\n"
  4. .LC1:
  5.         .string        "%d %d %d %d %d %d"
  6.         .text
  7.         .globl        main
  8.         .type        main, @function
  9. main:
  10.         pushl        %ebp
  11.         movl        %esp, %ebp
  12.         andl        $-16, %esp
  13.         subl        $96, %esp
  14.         movl        $4, 48(%esp)
  15.         movl        $3, 52(%esp)
  16.         movl        $1, 56(%esp)
  17.         movl        $5, 60(%esp)
  18.         movl        $1, 64(%esp)
  19.         movl        $2, 68(%esp)
  20.         movl        $3, 72(%esp)
  21.         movl        $4, 76(%esp)
  22.         movl        $0, 80(%esp)
  23.         movl        $9, 84(%esp)
  24.         movl        $5, 88(%esp)
  25.         movl        $7, 92(%esp)
  26.         movl        $2, 32(%esp)
  27.         movl        $4, 36(%esp)
  28.         movl        $5, 40(%esp)
  29.         movl        $6, 44(%esp)
  30.         movl        32(%esp), %eax
  31.         movl        %eax, 12(%esp)
  32.         leal        32(%esp), %eax
  33.         addl        $4, %eax
  34.         movl        %eax, 8(%esp)
  35.         leal        32(%esp), %eax
  36.         addl        $4, %eax
  37.         movl        %eax, 4(%esp)
  38.         movl        $.LC0, (%esp)
  39.         call        printf
  40.         movl        48(%esp), %eax
  41.         movl        %eax, 24(%esp)
  42.         leal        48(%esp), %eax
  43.         movl        %eax, 20(%esp)
  44.         leal        48(%esp), %eax
  45.         movl        %eax, 16(%esp)
  46.         leal        48(%esp), %eax
  47.         movl        %eax, 12(%esp)
  48.         leal        48(%esp), %eax
  49.         movl        %eax, 8(%esp)
  50.         leal        48(%esp), %eax
  51.         movl        %eax, 4(%esp)
  52.         movl        $.LC1, (%esp)
  53.         call        printf
  54. .L2:
  55.         jmp        .L2
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-2-25 19:17:47 | 显示全部楼层

回帖奖励 +5 鱼币

我不太懂,但是可以看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-2-25 20:20:32 | 显示全部楼层

回帖奖励 +5 鱼币

把二维数组看成是数组的数组,那么a指向的是a[0],a[0]指向的是a[0][0]的地址,可是为啥a,a[0],a[0][0]的地址相同,可是对他们取*操作结果却不一样,编译器内部是怎么处理的?

a[3][4] ,这里的a是数组名,是指针指向的首地址,a==a[0] ==a[0][0],*a等价于*(a+0)等价于 *((a+0)+0)
个人理解
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-2-25 21:48:55 | 显示全部楼层

回帖奖励 +5 鱼币

路过看看= =!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-2-25 22:46:11 | 显示全部楼层
渐渐的,我们会明白很多。加油吧!!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-2-26 10:58:04 | 显示全部楼层
char (*p)[20],是数组型指针,对应的二维数组 char (*p)[20]=char arr[3][20]={"aaaaaa","bbbb","ccccc"};
这里的p指向的是arr二维数组的首地址,那么
p+0指向了arr[0][0]的地址,即arr的地址
p+1指向了arr[1][0]的地址
p+2指向了arr[2][0]的地址
所以说可以理解了(*p)代表的一维,[20]也代表一维,,,只是char (*p)这个一维的步长是[20]罢了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-2-27 09:48:24 | 显示全部楼层
入过 谢谢楼主
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-2-27 10:16:39 | 显示全部楼层
看看。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-2-27 16:42:58 | 显示全部楼层
你试着地址+1就知道为什么了
&a
&a[0]
&a[0][0]
还有几个相等的表达方式我现在也忘了,反正你试一试就知道为什么了,其实很简单。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-2-27 19:32:01 | 显示全部楼层
楼主搞清楚明白了没有啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-2-27 21:48:57 | 显示全部楼层
首先将二数组a[3][4]看成是3个一维数组a[0],a[1],a[2],为了方便说明,a[0],a[1],a[2]对应a1,a2,a3,则一维数组为,例如:a1=a[0]={a[0][0],a[0][1],a[0][2],a[0][3]}  其他俩个一维数组(将二维拆分后的)a[1],a[2]也一样,省略不写、、、,
其中对于二维数组a[3][4]来说,a代表的是a【0]的地址,同时也是a[0][0]的地址,即a=&a[0][0],a的内容是一个内存地址,a【0】对于一维数组a1=a[0]={a[0][0],a[0][1],a[0][2],a[0][3]}也是一个指针,a【0】的内容也是一个内存地址


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

使用道具 举报

发表于 2014-2-27 22:01:56 | 显示全部楼层

回帖奖励 +5 鱼币

1.这个解释起来很复杂,不过你了解了二维数组的层次关系就很好理解了,a,a[0]在汇编代码中是一样的,但是当你用*的时候编译器会通过层次关系把*a处理成a[0],把*a[0]处理成a[0][0],所以你不要认为他们指向的内存地址相同就理解为他们是一样的……
2.第二个问题和第一个本质是一样的,你把多维数组当洋葱拨开就好了,而*就是拨开一层的工具,拨到具体地址的时候就是真正的值了。
可能你还是不能理解不过这东西其实你现在不着急马上就理解不,指针不必刻意去理解的,用多了 水到渠成就懂了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-19 15:40

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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