8.4.2 二维数组与指针
同一维数组一样,二维数组在定义时也返回了一个指向第一个元素的指针。而指针向后移动存储单元,可以访问数组中的元素。下面的代码定义了一个二维数组,然后将二维数组的头指针赋值给一个指针变量。
- 01 int a[4][5];
- 02 int *p;
- 03 p=a;
根据数组与指针的关系,可以用表8.4中的指针变量来访问数组中的所有变量。
表8.4 二维数组与指针
|
列 < xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
行 |
0 |
1 |
2 |
3 |
4 |
|
0 |
p |
p+1 |
p+2 |
p+3 |
p+4 |
|
1 |
p+5+0 |
p+5+1 |
p+5+2 |
p+5+3 |
p+5+4 |
|
2 |
p+5+5+0 |
p+5+5+1 |
p+5+5+2 |
p+5+5+3 |
p+5+5+4 |
|
3 |
p+15+0 |
p+15+1 |
p+15+2 |
p+15+3 |
p+15+4 |
从表8.4可知,数组中变量的指针地址与首指针存在着下面的关系。
q=p+(行数*总列数)+列数
根据这个关系,可以结合范例8-9所示的程序用指针的方法来访问一个数组。
【范例8-9】使用指针访问二维数组元素,实例代码如下所示。
实例代码8-9 \源文件\08\8.9.c
- 01 #include <stdio.h>
- 02 int main()
- 03 {
- 04 int i=10 , m , n ; /*定义3个变量。*/
- 05 int a[4][5]; /*定义1个4行5列的二维数组。*/
- 06 int *p; /*定义一个指针。*/
- 07 for(m=0;m<4;m++) /*行的循环。*/
- 08 {
- 09 for(n=0;n<5;n++) /*列的循环。*/
- 10 {
- 11 a[m][n]=i; /*对数组变量进行赋值。*/
- 12 i++; /*i自加。*/
- 13 }
- 14 }
- 15 p=a; /*把数组的头指针赋值给p。*/
- 16 for(m=0;m<4;m++) /*行循环。*/
- 17 {
- 18 for(n=0;n<5;n++) /*列循环。*/
- 19 {
- 20 printf("a[%d][%d]=%d ",m,n,*(p+(5*m)+n));/*用指针来访问数组的变量。*/
- 21 }
- 22 printf("\n"); /*每行输出一个换行。*/
- 23 }
- 24 return 0;
- 25 }
【执行结果】输入下面的命令,编译这个程序。- gcc 8.9.c
输入下面的命令,运行这个程序。- ./a.out
程序的运行结果如下所示。- a[0][0]=10 a[0][1]=11 a[0][2]=12 a[0][3]=13 a[0][4]=14
- a[1][0]=15 a[1][1]=16 a[1][2]=17 a[1][3]=18 a[1][4]=19
- a[2][0]=20 a[2][1]=21 a[2][2]=22 a[2][3]=23 a[2][4]=24
- a[3][0]=25 a[3][1]=26 a[3][2]=27 a[3][3]=28 a[3][4]=29
从程序的结果可知,用指针来访问数组,与用下标访问数组的效果是一样的。
【代码解析】代码第20行中表达式"*(p+5*m)+n)"的功能是计算数组元素的地址,"p"数组的首地址,"5*m"为一个含有5个元素的数组所占用的内存单元数目,则"p+{5*m}"可以计算出第m行的首地址,再加上n则表示第m行的第n个元素。