例10.13输出二维数组任一行任一列元素的值。
main()
{int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
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));
}
运行情况如下:
i=1,j=2(本行为键盘输入)
a[1,2]=13
注意应输入“i=1,j=2”,以与scanf函数中指定的字符串相对应。
程序第3行“int(*p)[4]”表示p是一个指针变量,它指向包含4个元素的一维数组。注意*p两侧的括号不可缺少,如果写成*p[4],由于方括号[]运算级别高,因此p先与[4]结合,是数组,然后再与前面的*结合,*p[4]是指针数组(见10.7节)。有的读者感到“(*p)[4]”这种形式不好理解。可以对下面二者做比较:
① int a[4];(a有4个元素,每个元素为整型)
② int (*p)[4];
第②种形式表示*p有4个元素,每个元素为整型。也就是p所指的对象是有4个整型元素的数组,即p是行指针,见图10.29。应该记住,此时p只能指向一个包含4个元素的一维数组,p的值就是该一维数组的首地址。p不能指向一维数组中的第j个元素。
程序中的p+i是二维数组a的第i行的地址(由于p是指向一维数组的指针变量,因此p加1,就指向下一个一维数组)。见图10.30。*(p+2)+3是a数组第2行第3列元素地址,这是指向列的指针,(p+2)+3)是a[2][3]的值。有的读者可能会想,(p+2)是第2行0列元素的地址,而p+2是第2行首地址,二者的值相同,(p+2)+3能否写成(p+2)+3呢?显然不行。因为(p+2)+3就成了(p+5)了,是第5行的首地址了。对“(p+2)+3”,括弧中的2是以一维数组的长度为单位的,即p每加1,地址就增加8个字节(4个元素,每个元素2个字节),而(p+2)+3括弧外的数字3,不是以p所指向的一维数组为长度单位的。而是采用p所指向的一维数组内部各元素的长度单位了,加3就是加(3×2)个字节。p+2和(p+2)具有相同的值,但(p+2)+3和(p+2)+3的值就不相同了。这和上一节所叙述的概念是一致的。
main()
{int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
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));
}
运行情况如下:
i=1,j=2(本行为键盘输入)
a[1,2]=13
注意应输入“i=1,j=2”,以与scanf函数中指定的字符串相对应。
程序第3行“int(*p)[4]”表示p是一个指针变量,它指向包含4个元素的一维数组。注意*p两侧的括号不可缺少,如果写成*p[4],由于方括号[]运算级别高,因此p先与[4]结合,是数组,然后再与前面的*结合,*p[4]是指针数组(见10.7节)。有的读者感到“(*p)[4]”这种形式不好理解。可以对下面二者做比较:
① int a[4];(a有4个元素,每个元素为整型)
② int (*p)[4];
第②种形式表示*p有4个元素,每个元素为整型。也就是p所指的对象是有4个整型元素的数组,即p是行指针,见图10.29。应该记住,此时p只能指向一个包含4个元素的一维数组,p的值就是该一维数组的首地址。p不能指向一维数组中的第j个元素。
程序中的p+i是二维数组a的第i行的地址(由于p是指向一维数组的指针变量,因此p加1,就指向下一个一维数组)。见图10.30。*(p+2)+3是a数组第2行第3列元素地址,这是指向列的指针,(p+2)+3)是a[2][3]的值。有的读者可能会想,(p+2)是第2行0列元素的地址,而p+2是第2行首地址,二者的值相同,(p+2)+3能否写成(p+2)+3呢?显然不行。因为(p+2)+3就成了(p+5)了,是第5行的首地址了。对“(p+2)+3”,括弧中的2是以一维数组的长度为单位的,即p每加1,地址就增加8个字节(4个元素,每个元素2个字节),而(p+2)+3括弧外的数字3,不是以p所指向的一维数组为长度单位的。而是采用p所指向的一维数组内部各元素的长度单位了,加3就是加(3×2)个字节。p+2和(p+2)具有相同的值,但(p+2)+3和(p+2)+3的值就不相同了。这和上一节所叙述的概念是一致的。