VIsǐοΝ__㊣ 发表于 2014-4-15 14:18:42

求助指针和多维数组

#include <stdio.h>

void main()
{
        int a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };

        printf("a: %d\n", a);

        printf("*a: %d\n", *a);

        printf("a: %d\n", a);

        printf("&a: %d\n", &a);

        printf("&a: %d\n", &a);

        printf("a+1: %d\n", a + 1);

        printf("*(a+1): %d\n", *(a + 1));

        printf("a: %d\n", a);

        printf("&a: %d\n", &a);

        printf("&a: %d\n", &a);

        printf("a+2: %d\n", a + 2);

        printf("*(a+2): %d\n", *(a + 2));

        printf("a: %d\n", a);

        printf("&a: %d\n", &a);

        printf("&a: %d\n", &a);

        printf("a+1: %d\n", a + 1);

        printf("*(a+1)+1: %d\n", *(a + 1) + 1);

        printf("*(a+1): %d\n", *(a + 1));

        printf("*(*(a+1)+1): %d\n", *(*(a + 1) + 1));

}
谁能给我具体解释一下啊,我完全不懂这都指的是什么和什么。
学到指针这一章我全蒙了,求大神帮助我!

青玄 发表于 2014-4-15 14:18:43

其实,我想是这样的:虽然,printf();中给出的参数不一样,一个是数组名,而一个是取数组的地址,但是他们在内存中的空间是同一个空间,也就是在同一个栈空间,这样吧!我把他反汇编了,你看一下,就明白了,上面也有我的注释:
5:            int a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };   //这里是定义二维数组
00401028   mov         dword ptr ,0                  ;将数组中的0放到的这个空间里面,ebp是扩展基址寄存器
0040102F   mov         dword ptr ,1
00401036   mov         dword ptr ,2
0040103D   mov         dword ptr ,3
00401044   mov         dword ptr ,4
0040104B   mov         dword ptr ,5
00401052   mov         dword ptr ,6
00401059   mov         dword ptr ,7
00401060   mov         dword ptr ,8
00401067   mov         dword ptr ,9
0040106E   mov         dword ptr ,0Ah
00401075   mov         dword ptr ,0Bh
6:
7:            printf("a: %d\n", a);
0040107C   lea         eax,             ;注意:这里是将的内容,也就是数组中的0放到eax里面
0040107F   push      eax   ;将a的参数推入栈中
00401080   push      offset string "a: %d\n" (0042212c)
00401085   call      printf (00401240)   ;调用printf()函数
0040108A   add         esp,8
8:
9:            printf("*a: %d\n", *a);
0040108D   lea         ecx,            ;注意:这里也是将的内容放到ecx里面,也就是说在数组中数组名指的就是数组的首地址,然后通过
00401090   push      ecx                     ;偏移进行索引,下面的也都是这样的,虽然他们一个是数组名,一个是指针,但是他们指的都是同一个空间,
00401091   push      offset string "*a: %d\n" (00422120);它们在栈里面的空间是一样的
00401096   call      printf (00401240)
0040109B   add         esp,8
10:
11:         printf("a: %d\n", a);
0040109E   lea         edx,
004010A1   push      edx
004010A2   push      offset string "a: %d\n" (00422114)
004010A7   call      printf (00401240)
004010AC   add         esp,8
12:
13:         printf("&a: %d\n", &a);
004010AF   lea         eax,
004010B2   push      eax
004010B3   push      offset string "&a: %d\n" (00422104)
004010B8   call      printf (00401240)
004010BD   add         esp,8
14:
15:         printf("&a: %d\n", &a);
004010C0   lea         ecx,
004010C3   push      ecx
004010C4   push      offset string "&a: %d\n" (004220f4)
004010C9   call      printf (00401240)
004010CE   add         esp,8
16:
17:         printf("a+1: %d\n", a + 1);
004010D1   lea         edx,
004010D4   push      edx
004010D5   push      offset string "a+1: %d\n" (004220e8)
004010DA   call      printf (00401240)
004010DF   add         esp,8
18:
19:         printf("*(a+1): %d\n", *(a + 1));
004010E2   lea         eax,
004010E5   push      eax
004010E6   push      offset string "*(a+1): %d\n" (004220d8)
004010EB   call      printf (00401240)
004010F0   add         esp,8
20:
21:         printf("a: %d\n", a);
004010F3   lea         ecx,
004010F6   push      ecx
004010F7   push      offset string "a: %d\n" (004220cc)
004010FC   call      printf (00401240)
00401101   add         esp,8
22:
23:         printf("&a: %d\n", &a);
00401104   lea         edx,
00401107   push      edx
00401108   push      offset string "&a: %d\n" (004220bc)
0040110D   call      printf (00401240)
00401112   add         esp,8
24:
25:         printf("&a: %d\n", &a);
00401115   lea         eax,
00401118   push      eax
00401119   push      offset string "&a: %d\n" (004220ac)
0040111E   call      printf (00401240)
00401123   add         esp,8
26:
27:         printf("a+2: %d\n", a + 2);
00401126   lea         ecx,
00401129   push      ecx
0040112A   push      offset string "a+2: %d\n" (004220a0)
0040112F   call      printf (00401240)
00401134   add         esp,8
28:
29:         printf("*(a+2): %d\n", *(a + 2));
00401137   lea         edx,
0040113A   push      edx
0040113B   push      offset string "*(a+2): %d\n" (00422090)
00401140   call      printf (00401240)
00401145   add         esp,8
30:
31:         printf("a: %d\n", a);
00401148   lea         eax,
0040114B   push      eax
0040114C   push      offset string "a: %d\n" (00422084)
00401151   call      printf (00401240)
00401156   add         esp,8
32:
33:         printf("&a: %d\n", &a);
00401159   lea         ecx,
0040115C   push      ecx
0040115D   push      offset string "&a: %d\n" (00422074)
00401162   call      printf (00401240)
00401167   add         esp,8
34:
35:         printf("&a: %d\n", &a);
0040116A   lea         edx,
0040116D   push      edx
0040116E   push      offset string "&a: %d\n" (00422064)
00401173   call      printf (00401240)
00401178   add         esp,8
36:
37:         printf("a+1: %d\n", a + 1);
0040117B   lea         eax,
0040117E   push      eax
0040117F   push      offset string "a+1: %d\n" (00422054)
00401184   call      printf (00401240)
00401189   add         esp,8
38:
39:         printf("*(a+1)+1: %d\n", *(a + 1) + 1);
0040118C   lea         ecx,
0040118F   push      ecx
00401190   push      offset string "*(a+1)+1: %d\n" (00422044)
00401195   call      printf (00401240)
0040119A   add         esp,8
40:
41:         printf("*(a+1): %d\n", *(a + 1));
0040119D   mov         edx,dword ptr
004011A0   push      edx
004011A1   push      offset string "*(a+1): %d\n" (00422030)
004011A6   call      printf (00401240)
004011AB   add         esp,8
42:
43:         printf("*(*(a+1)+1): %d\n", *(*(a + 1) + 1));
004011AE   mov         eax,dword ptr
004011B1   push      eax
004011B2   push      offset string "*(*(a+1)+1): %d\n" (0042201c)
004011B7   call      printf (00401240)
004011BC   add         esp,8
44:
45:   }
004011BF   pop         edi
004011C0   pop         esi
004011C1   pop         ebx
004011C2   add         esp,70h
004011C5   cmp         ebp,esp
004011C7   call      __chkesp (004012c0)
004011CC   mov         esp,ebp
004011CE   pop         ebp
004011CF   ret


杨学子 发表于 2014-4-15 14:23:54

好好看下甲鱼老师讲的,多看 有技巧的记

天使之约 发表于 2014-4-21 21:39:19

设数组a的首地址为1000 :
int a={{0,1,2,3}, {4,5,6,7}, {8,9,10,11}}
*(a+0)==>a是第一个一维数组的数组名和首地址
*a==>*(a+0)==>a是第一个一维数组的数组名和首地址

从二维数组的角度来看,a是二维数组名,a代表整个二维数组的首地址,也是二维数组0行的首地址a+1代表第一行的首地址。

a是第一个一维数组的数组名和首地址,因此也为1000。
*(a+0)或*a是与a等效的, 它表示一维数组a 0 号元素的首地址,也为1000。
&a是二维数组a的0行0列元素首地址,同样是1000。
因此,a,a,*(a+0),*a,&a是相等的。
同理,a+1是二维数组1行的首地址,等于1008。
a是第二个一维数组的数组名和首地址,因此也为1008。
&a是二维数组a的1行0列元素地址,也是1008。
因此a+1,a,*(a+1),&a是等同的。
由此可得出:a+i,a,*(a+i),&a是等同的。
此外,&a和a也是等同的。
因为在二维数组中不能把&a理解为元素a的地址,不存在元素a。C语言规定,它是一种地址计算方法,表示数组a第i行首地址。
由此,我们得出:a,&a,*(a+i)和a+i也都是等同的。
另外,a也可以看成是a+0,是一维数组a的0号元素的首地址,而a+1则是a的1号元素首地址,由此可得出a+j则是一维数组a的j号元素首地址,它等于&a。

由a=*(a+i)得a+j=*(a+i)+j。由于*(a+i)+j是二维数组a的i行j列元素的首地址,所以,该元素的值等于*(*(a+i)+j)。

喜欢散步 发表于 2014-4-23 22:14:38

上面的很好了, 讲得。
页: [1]
查看完整版本: 求助指针和多维数组