原创 C指针温习(三):多维数组与指针

2007-12-26 18:05 5542 7 7 分类: MCU/ 嵌入式

我们可以这样认为:二维数组是“数组的数组”,即数组a是由3个一维数组所组成的。


C语言规定:在二维数组当中,a代表二维数组首元素的地址,但这和一维数组不同,二维数组的首元素是由它的列数个元素所组成的一维数组,它并不是一个整型变量。比如上面这个例子,首元素是由四个整型元素所组成的。所以,a代表首行(第零行)的首地址, a+1代表第一行的首地址。如果首行首地址是2000,则a+1就是2000+2*4=2008。它表示a[1]的地址。


我们可以看到,a[0]a[1]a[2]是一维数组名,而C又规定了数组名代表数组首元素的地址,所以a[0]代表一维数组a[0]中第零列元素的地址。即&a[0][0]


那么第0行第1列元素的地址怎么表示呢?a[0]是一维数组名,它的第二个元素显然应该用a[0]+1来表示。所以,如果a[0]的值是2000,那么a[0]+1的值是2002(与a+1不同,a+12008)。所以我们不难明白,a[0]+0a[0]+1a[0]+2分别是a[0][0]a[0][1]a[0][2]元素的地址,即:& a[0][0]&a[0][1]&a[0][2]


前面已经讲过,a*a+i)等价,所以,a[0]+1*a+0+1等价,它们的值都是& a[0][1],注意,不要将*a+0+1写成了*a+0+1),后者变成了*a+1)了。相当于a[1]


如果我们想得到a[0][1]的值,用地址法怎么表示呢?既然a[0]+1*a+0+1a[0][1]的地址,那么,*a[0]+1)和**a+0+1)就是a[0][1]的值。即:*a+j)和**a+i+j)就是a[j]的值。


现列表一张(在老谭的书上有):



表示形式


含义


地址


a


二维数组名,指向一维数组a[0],即第0行首地址


2000


a[0]*a+0),*a


0行第0列元素地址


2000


a+1, &a[1]


第一行首地址


2008


a[1],*(a+1)


第一行第零列元素a[1][0]的地址


2008


a[1]+2, *(a+1)+2, &a[1][2]


第一行第二列元素a[1][2]的地址


2012


*a[1]+2,**a+1+2


第一行第二列元素a[1][2]的值


元素值为13


二维数组名(a)地指向行的,所以a+1 中的1表示一行中全部元素所占的字节数数。一维数组名(如a[0])是指向列的。a[0]+1中的1表示一个元素所占的字节数。在指向行的指针前面加一个*,就转换成为了指向列的指针。反之,在指向列的指针前面加&,就成为了指向行的指针。


不要把&a简单地理解为a的物理地址,因为并不存在a这样一个实际的变量,它只是一种子选手地址的计算方法,能够得到第i行的首地址。&aa的值是一样的,但是含义却不同。&aa+i是指向行的,但是a*a+i)是指向列的。在二维数组中,a+i= a= *a+i=&a=*a[0]。即它们的地址值是相等的。


指针变量可以指向数组元素,也可以指向由m个元素组成的一组数组。


例子(指向数组元素):


#include "stdio.h"


main()


{


    int a[3][4] = {{2,3,5,6},{2,7,8,12},{23,15,17,11}};


    int (* p)[4],i,j;


    p = a;


    scanf("i=%d,j=%d",&i,&j);


    printf("a[%d,%d]=%d\n",i,j,*(*(p+i)+j));


    getch();


}


这个程序第三行中“int (* p)[4]”表示p是一个指针变量,它指向包含四个整型元素的一维数组。注意那个括号不可缺少,如果写成*p[4],由于[ ]的运算级别高,因此,p先与[ ]结合,是数组,再与*结合,所以*p[4]是指针数组。


我们作以下比较:


int a[4]; /*a有四个元素,每个元素为整型*/


int (* p)[4];第二种形式是表示*p有四个元素,每个元素为整型,也就是p所指的对象是有四个整型元素的数组,即p是行指针。应该明白的是:这个时候p只能指向一个包含四个元素的一维数组,p的值就是一维数组的首地址,p不能指向一维数组中的第j个元素。


下面举个例子说明指向数组的指针作函数参数的例子:


#include <stdio.h>


<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 


void average( float * p,int n )


{


    float * p_end;


    float sum = 0,aver;


    p_end = p+n-1;


    for( ;p<= p_end;p++ )


        sum = sum+(*p);


    aver = sum/n;


    printf("average = %<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />5.2f\n",aver );


}


 


void search( float (*p)[4],int n ) /* *p是指向有四个元素的一维数组的指针*/


{


    int i;


    printf("the score of No.%d are :\n",n);


    for(i = 0;i<4;i++ )


    printf("%5.2f",*(*(p+n)+i));


}


 


void main()


{


    float score[3][4] = {{54,23,66,78},{98,76,55,87},{98,99,100,89}};


    average( * score,12 );  /* 12个分数的平均分*/


    search( score,2 );  /*求序号为2的学生的成绩*/


    getch();


}


 


 

文章评论0条评论)

登录后参与讨论
我要评论
0
7
关闭 站长推荐上一条 /2 下一条