鱼C论坛

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

二维数组与指针的关系

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

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

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

x
#include <stdio.h>
int main()
{   
    int a[3][4]={{4,3,1,5},{1,2,3,4},{0,9,5,7}};
    int b[4]={2,4,5,6};
    printf("%d %d %d\n",b+1,&b[1],*b);
    printf("%d %d %d %d %d %d",&a,a,*a,a[0],&a[0],a[0][0]);
    while(1);
    return 0;
}
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 | 显示全部楼层
如果你能看懂汇编的话。。
        .section        .rodata
.LC0:
        .string        "%d %d %d\n"
.LC1:
        .string        "%d %d %d %d %d %d"
        .text
        .globl        main
        .type        main, @function
main:
        pushl        %ebp
        movl        %esp, %ebp
        andl        $-16, %esp
        subl        $96, %esp
        movl        $4, 48(%esp)
        movl        $3, 52(%esp)
        movl        $1, 56(%esp)
        movl        $5, 60(%esp)
        movl        $1, 64(%esp)
        movl        $2, 68(%esp)
        movl        $3, 72(%esp)
        movl        $4, 76(%esp)
        movl        $0, 80(%esp)
        movl        $9, 84(%esp)
        movl        $5, 88(%esp)
        movl        $7, 92(%esp)
        movl        $2, 32(%esp)
        movl        $4, 36(%esp)
        movl        $5, 40(%esp)
        movl        $6, 44(%esp)
        movl        32(%esp), %eax
        movl        %eax, 12(%esp)
        leal        32(%esp), %eax
        addl        $4, %eax
        movl        %eax, 8(%esp)
        leal        32(%esp), %eax
        addl        $4, %eax
        movl        %eax, 4(%esp)
        movl        $.LC0, (%esp)
        call        printf
        movl        48(%esp), %eax
        movl        %eax, 24(%esp)
        leal        48(%esp), %eax
        movl        %eax, 20(%esp)
        leal        48(%esp), %eax
        movl        %eax, 16(%esp)
        leal        48(%esp), %eax
        movl        %eax, 12(%esp)
        leal        48(%esp), %eax
        movl        %eax, 8(%esp)
        leal        48(%esp), %eax
        movl        %eax, 4(%esp)
        movl        $.LC1, (%esp)
        call        printf
.L2:
        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-12-24 10:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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