我们可以这样认为:二维数组是“数组的数组”,即数组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+1是2008)。所以我们不难明白,a[0]+0、a[0]+1、a[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)+1是a[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行的首地址。&a和a的值是一样的,但是含义却不同。&a和a+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条评论)
登录后参与讨论