理解多维数组

    今天突然发现自己对多维数组的指针的理解出现了偏差,于是做了些实验:

#include<stdio.h>

int main()
{
int n[3][3];
void print(int *t);
int s=0,i,j;
printf("%d\n",n);
for(i=0;i<3;i++)
{
                    printf("%d\n",n[i]);
for(j=0;j<3;j++)
{
n[i][j]=s;
printf("%d ",&n[i][j]);
s++;
}
printf("\n");
}
system("pause");
printf("n:%d\n",n);
printf("*n:%d\n",*n);
printf("**n:%d\n",**n);
printf("*(n+1):%d\n",*(n+1));
printf("**(n+1):%d\n",**(n+1));
printf("*n[1]:%d\n",*n[1]);
print(n);
system("pause");
}
void print(int *t)
{
int m=0,n=0;
for(m=0;m<3;m++)
{
for(n=0;n<3;n++)
{
printf("%d ",*(t+3*m+n));
}
printf("\n");
}
return;

}

结果为:

2686736
2686736
2686736 2686740 2686744
2686748
2686748 2686752 2686756
2686760
2686760 2686764 2686768
请按任意键继续. . .
n:2686736
*n:2686736
**n:0
*(n+1):2686748
**(n+1):3
*n[1]:3
0 1 2
3 4 5
6 7 8
请按任意键继续. . .

    以下摘自谭老师的C语言课本:

    a[i]从形式上来看是a数组中序号为i的元素。如果a是一维数组名,则a[i]代表a数组中序号为i的元素所占的内存单元中的内容。a[i]是有物理地址的,是占内存单元的。但如果a[i]是二维数组,则a[i]是代表一维数组名。它只是一个地址,并不代表某一元素的值(如同一维数组名只是个指针常量一样)。a、a+i、a[i]、*(a+i)、a[i]+j都是地址。

    不要把&a[i]简单地理解为a[i]单元的物理地址,因为并不存在a[i]这样一个实际的变量。它只是一种地址的计算方法,能得到第i行的首地址,&a[i]和a[i]的值是一样的,但是它们的含义是不一样的。&a[i]或a+i指向行,而a[i]或*(a+i)指向列,它们所指向的对象是不同的,即指针的类型是不同的。

    为了进一步理解编译器对于数组的处理,又做了个实验,编写test.c代码如下:

int num[10];
int a;
int *p=num;
int *q=&num[2];
int fuct(int *x,int * y)
{
int a;
a=0;
a+=*(x+1);
a+=*(y+3);
return a;
}

    用gcc编译器将之转换为内部as汇编代码如下:

.file "test.c"
.comm _num, 40, 5
.comm _a, 4, 2
.globl _p
.data
.align 4
_p:
.long _num
.globl _q
.align 4
_q:
.long _num+8
.text
.globl _fuct
.def _fuct; .scl 2; .type 32; .endef
_fuct:
LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $16, %esp
movl $0, -4(%ebp)
movl 8(%ebp), %eax
addl $4, %eax
movl (%eax), %eax
addl %eax, -4(%ebp)
movl 12(%ebp), %eax
addl $12, %eax
movl (%eax), %eax
addl %eax, -4(%ebp)
movl -4(%ebp), %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE0:

    由汇编代码可以看出,编译器在处理数组时,只记下了数组名,并将之视为常量来处理,数组中的所有元素都是通过这个地址常量加上偏移地址间接得到的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值