鱼C论坛

 找回密码
 立即注册
查看: 1782|回复: 4

求助指针和多维数组

[复制链接]
发表于 2014-4-15 14:18:42 | 显示全部楼层 |阅读模式
5鱼币
#include <stdio.h>

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

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

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

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

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

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

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

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

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

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

        printf("&a[1][0]: %d\n", &a[1][0]);

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

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

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

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

        printf("&a[2][0]: %d\n", &a[2][0]);

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

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

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

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

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

最佳答案

查看完整内容

其实,我想是这样的:虽然,printf();中给出的参数不一样,一个是数组名,而一个是取数组的地址,但是他们在内存中的空间是同一个空间,也就是在同一个栈空间,这样吧!我把他反汇编了,你看一下,就明白了,上面也有我的注释: 5: int a[3][4] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; //这里是定义二维数组 00401028 mov dword ptr [ebp-30h],0 ;将数组中的0放到[ebp-30h]的这个 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-4-15 14:18:43 | 显示全部楼层
其实,我想是这样的:虽然,printf();中给出的参数不一样,一个是数组名,而一个是取数组的地址,但是他们在内存中的空间是同一个空间,也就是在同一个栈空间,这样吧!我把他反汇编了,你看一下,就明白了,上面也有我的注释:
5:            int a[3][4] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };   //这里是定义二维数组
00401028   mov         dword ptr [ebp-30h],0                  ;将数组中的0放到[ebp-30h]的这个空间里面,ebp是扩展基址寄存器
0040102F   mov         dword ptr [ebp-2Ch],1
00401036   mov         dword ptr [ebp-28h],2
0040103D   mov         dword ptr [ebp-24h],3
00401044   mov         dword ptr [ebp-20h],4
0040104B   mov         dword ptr [ebp-1Ch],5
00401052   mov         dword ptr [ebp-18h],6
00401059   mov         dword ptr [ebp-14h],7
00401060   mov         dword ptr [ebp-10h],8
00401067   mov         dword ptr [ebp-0Ch],9
0040106E   mov         dword ptr [ebp-8],0Ah
00401075   mov         dword ptr [ebp-4],0Bh
6:
7:            printf("a: %d\n", a);
0040107C   lea         eax,[ebp-30h]             ;注意:这里是将[ebp-30h]的内容,也就是数组中的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,[ebp-30h]            ;注意:这里也是将[ebp-30h]的内容放到ecx里面,也就是说在数组中数组名指的就是数组的首地址,然后通过
00401090   push        ecx                       ;偏移进行索引,下面的也都是这样的,虽然他们一个是数组名,一个是指针,但是他们指的都是同一个空间,
00401091   push        offset string "*a: %d\n" (00422120)  ;它们在栈里面的空间是一样的
00401096   call        printf (00401240)
0040109B   add         esp,8
10:
11:           printf("a[0]: %d\n", a[0]);
0040109E   lea         edx,[ebp-30h]
004010A1   push        edx
004010A2   push        offset string "a[0]: %d\n" (00422114)
004010A7   call        printf (00401240)
004010AC   add         esp,8
12:
13:           printf("&a[0]: %d\n", &a[0]);
004010AF   lea         eax,[ebp-30h]
004010B2   push        eax
004010B3   push        offset string "&a[0]: %d\n" (00422104)
004010B8   call        printf (00401240)
004010BD   add         esp,8
14:
15:           printf("&a[0][0]: %d\n", &a[0][0]);
004010C0   lea         ecx,[ebp-30h]
004010C3   push        ecx
004010C4   push        offset string "&a[0][0]: %d\n" (004220f4)
004010C9   call        printf (00401240)
004010CE   add         esp,8
16:
17:           printf("a+1: %d\n", a + 1);
004010D1   lea         edx,[ebp-20h]
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,[ebp-20h]
004010E5   push        eax
004010E6   push        offset string "*(a+1): %d\n" (004220d8)
004010EB   call        printf (00401240)
004010F0   add         esp,8
20:
21:           printf("a[1]: %d\n", a[1]);
004010F3   lea         ecx,[ebp-20h]
004010F6   push        ecx
004010F7   push        offset string "a[1]: %d\n" (004220cc)
004010FC   call        printf (00401240)
00401101   add         esp,8
22:
23:           printf("&a[1]: %d\n", &a[1]);
00401104   lea         edx,[ebp-20h]
00401107   push        edx
00401108   push        offset string "&a[1]: %d\n" (004220bc)
0040110D   call        printf (00401240)
00401112   add         esp,8
24:
25:           printf("&a[1][0]: %d\n", &a[1][0]);
00401115   lea         eax,[ebp-20h]
00401118   push        eax
00401119   push        offset string "&a[1][0]: %d\n" (004220ac)
0040111E   call        printf (00401240)
00401123   add         esp,8
26:
27:           printf("a+2: %d\n", a + 2);
00401126   lea         ecx,[ebp-10h]
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,[ebp-10h]
0040113A   push        edx
0040113B   push        offset string "*(a+2): %d\n" (00422090)
00401140   call        printf (00401240)
00401145   add         esp,8
30:
31:           printf("a[2]: %d\n", a[2]);
00401148   lea         eax,[ebp-10h]
0040114B   push        eax
0040114C   push        offset string "a[2]: %d\n" (00422084)
00401151   call        printf (00401240)
00401156   add         esp,8
32:
33:           printf("&a[2]: %d\n", &a[2]);
00401159   lea         ecx,[ebp-10h]
0040115C   push        ecx
0040115D   push        offset string "&a[2]: %d\n" (00422074)
00401162   call        printf (00401240)
00401167   add         esp,8
34:
35:           printf("&a[2][0]: %d\n", &a[2][0]);
0040116A   lea         edx,[ebp-10h]
0040116D   push        edx
0040116E   push        offset string "&a[2][0]: %d\n" (00422064)
00401173   call        printf (00401240)
00401178   add         esp,8
36:
37:           printf("a[1]+1: %d\n", a[1] + 1);
0040117B   lea         eax,[ebp-1Ch]
0040117E   push        eax
0040117F   push        offset string "a[1]+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,[ebp-1Ch]
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]+1): %d\n", *(a[1] + 1));
0040119D   mov         edx,dword ptr [ebp-1Ch]
004011A0   push        edx
004011A1   push        offset string "*(a[1]+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 [ebp-1Ch]
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


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

使用道具 举报

发表于 2014-4-15 14:23:54 | 显示全部楼层
好好看下甲鱼老师讲的,多看 有技巧的记
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-4-21 21:39:19 | 显示全部楼层
设数组a的首地址为1000 :
int a[3][4]={{0,1,2,3}, {4,5,6,7}, {8,9,10,11}}
*(a+0)==>a[0]是第一个一维数组的数组名和首地址
*a==>*(a+0)==>a[0]是第一个一维数组的数组名和首地址

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

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

由a[i]=*(a+i)得a[i]+j=*(a+i)+j。由于*(a+i)+j是二维数组a的i行j列元素的首地址,所以,该元素的值等于*(*(a+i)+j)。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-4-23 22:14:38 | 显示全部楼层
上面的很好了, 讲得。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-26 11:16

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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