mrzoro67 发表于 2014-2-25 17:53:41

二维数组与指针的关系

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

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

枫界易城 发表于 2014-2-25 18:24:28

看看,,,,,,

oggplay 发表于 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

jiangyuming0434 发表于 2014-2-25 19:17:47

我不太懂,但是可以看看

walykyy 发表于 2014-2-25 20:20:32

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

a ,这里的a是数组名,是指针指向的首地址,a==a ==a,*a等价于*(a+0)等价于 *((a+0)+0)
个人理解

未闻丶花名 发表于 2014-2-25 21:48:55

路过看看= =!

___佳ヾ↘ 发表于 2014-2-25 22:46:11

渐渐的,我们会明白很多。加油吧!!!!

ヾ_浪淘沙シ 发表于 2014-2-26 10:58:04

char (*p),是数组型指针,对应的二维数组 char (*p)=char arr={"aaaaaa","bbbb","ccccc"};
这里的p指向的是arr二维数组的首地址,那么
p+0指向了arr的地址,即arr的地址
p+1指向了arr的地址
p+2指向了arr的地址
所以说可以理解了(*p)代表的一维,也代表一维,,,只是char (*p)这个一维的步长是罢了

g135176 发表于 2014-2-27 09:48:24

入过 谢谢楼主

913174287 发表于 2014-2-27 10:16:39

看看。。。。

394428311 发表于 2014-2-27 16:42:58

你试着地址+1就知道为什么了
&a
&a
&a
还有几个相等的表达方式我现在也忘了,反正你试一试就知道为什么了,其实很简单。

zhaopengfei 发表于 2014-2-27 19:32:01

楼主搞清楚明白了没有啊

FXW 发表于 2014-2-27 21:48:57

首先将二数组a看成是3个一维数组a,a,a,为了方便说明,a,a,a对应a1,a2,a3,则一维数组为,例如:a1=a={a,a,a,a}其他俩个一维数组(将二维拆分后的)a,a也一样,省略不写、、、,
其中对于二维数组a来说,a代表的是a【0]的地址,同时也是a的地址,即a=&a,a的内容是一个内存地址,a【0】对于一维数组a1=a={a,a,a,a}也是一个指针,a【0】的内容也是一个内存地址


飞蛤 发表于 2014-2-27 22:01:56

1.这个解释起来很复杂,不过你了解了二维数组的层次关系就很好理解了,a,a在汇编代码中是一样的,但是当你用*的时候编译器会通过层次关系把*a处理成a,把*a处理成a,所以你不要认为他们指向的内存地址相同就理解为他们是一样的……
2.第二个问题和第一个本质是一样的,你把多维数组当洋葱拨开就好了,而*就是拨开一层的工具,拨到具体地址的时候就是真正的值了。
可能你还是不能理解不过这东西其实你现在不着急马上就理解不,指针不必刻意去理解的,用多了 水到渠成就懂了
页: [1]
查看完整版本: 二维数组与指针的关系