指针与二维数组
1、学习目标
- 指针与二维数组-掌握
- 总结与思考
2、指针与二维数组
-
多维数组就是具有两个或以上下标的数组,在C语言中,二维数组的元素连续存储,按行优先存。
-
编程实现,使用一级指针(一个*是一级指针)遍历二维数组。
#include <stdio.h> int main() { int a[3][2] = {{1,6},{9,12},{61,12}}; int *p, i, n; n = sizeof(a) / sizeof(int); printf("n=%d\n", n); // p = a;执行会报警告,类型不兼容。 p = a[0];// p = &a[0][0] printf("%p %p\n", p, p+1);//p, p+1是一个一个的移动 printf("%p %p\n", a, a+1);//a, a+1是一行一行的移动 for(i = 0; i < n; i++) printf("%d ",*(p+i)); puts(""); return 0; }
运行结果:
$ ./app n=6 0x7ffd25b44f70 0x7ffd25b44f74// a[0][0]和a[0][1]相差4个字节 0x7ffd25b44f70 0x7ffd25b44f78// a[0][0]和a[1][0]相差8个字节 1 6 9 12 61 12
-
可把二维数组看作由多个一维数组组成。
-
比如 int a[3] [3],含有三个元素:a[0],a[1],a[2]
-
元素a[0],a[1],a[2]都是一维数组名
-
数组名不能进行自增(++),自减(–)计算。
-
sizeof(一维数组名)可以计算该行的内存空间。
-
示例:
#include <stdio.h> int main() { int a[3][2] = {{1,6},{9,12},{61,12}}; int *p, i, n; n = sizeof(a) / sizeof(int); a[1]++;//错误的,自增需要是变量,不能是常量 p = a[0];// p = &a[0][0] for(i = 0; i < n; i++) printf("%d ",*(p+i)); puts(""); return 0; }
运行结果:
$ gcc -o app d12.c d12.c: In function ‘main’: d12.c:11:6: error: lvalue required as increment operand a[1]++; ^
#include <stdio.h> int main() { int a[3][2] = {{1,6},{9,12},{61,12}}; int *p, i, n; n = sizeof(a) / sizeof(int); printf("%d\n", sizeof(a[1])); p = a[0];// p = &a[0][0] for(i = 0; i < n; i++) printf("%d ",*(p+i)); puts(""); return 0; }
运行结果:
$ ./app 8 1 6 9 12 61 12
-
-
二维数组名代表数组的起始地址,数组名加1,是移动一行元素,因此二维数组名常被称为行地址。
-
示例:加*改变了指针的性质,从行指针变成了一级指针。
#include <stdio.h> int main() { int a[3][2] = {{1,6},{9,12},{61,12}}; int *p, i, n; n = sizeof(a) / sizeof(int); printf("%p %p\n", a, a+1); printf("%p %p\n", a[0], a[0]+1);//a[0]<=>*a printf("%p %p\n", *a, *a+1);//加*就改变了指针的性质 return 0; }
运行结果:
$ ./app 0x7fff6ae3d4c0 0x7fff6ae3d4c8 0x7fff6ae3d4c0 0x7fff6ae3d4c4 0x7fff6ae3d4c0 0x7fff6ae3d4c4
-
行指针(数组指针)
存储行指针的指针变量,叫做行指针变量,形式如下:
-
<存储类型> <数据类型> (*<指针变量名>)[表达式];
-
例如:int a[2] [3]; int (*p)[3]//增加该语句可以满足p+1移动一行的功能
-
方括号中的常量表达式表示指针加1,移动几个数据。
-
当用行指针操作二维数组时,表达式一般写成1行的元素个数,即列数。
-
示例验证:使用行指针表示二维数组int a[3] [2]的元素a[1] [1]
#include <stdio.h> int main() { int a[3][2] = {{1,6},{9,12},{61,12}}; int (*p)[2]; p = a; printf("%p %p\n", a, a+1); printf("%p %p\n", p, p+1); //通过地址验证a[1][1]和p[1][1] printf("%d %d\n", a[1][1], p[1][1]); printf("%d %d\n", *(*(a+1)+1), *(*(p+1)+1)); //a[1][1]和*(*(a+1)+1)是一样的 return 0; }
运行结果:a, a+1和p, p+1地址相同,a[1] [1]和p[1] [1]相同(表达某一个元素)
$ ./app 0x7fff2a79d840 0x7fff2a79d848 0x7fff2a79d840 0x7fff2a79d848 12 12 12 12
使用行指针遍历二维数组
#include <stdio.h> int main() { int a[3][2] = {{1,6},{9,12},{61,12}}; int (*p)[2], i, j; p = a; for(i = 0; i < 3; i++){ for(j = 0; j < 2; j++) printf("%d %d %d %d ", a[i][j], p[i][j], *(*(a+i)+j), *(*(p+i)+j)); puts(""); } return 0; }
运行结果:
$ ./app 1 1 1 1 6 6 6 6 9 9 9 9 12 12 12 12 61 61 61 61 12 12 12 12
-
3、总结与思考
-
主要介绍了指针与二维数组,包括一级指针如何访问二维数组以及行指针如何访问二维数组。
-
思考:
-
二维数组名有什么特点?
二维数组名代表数组的起始地址,数组名加1,是移动一行元素,因此二维数组名常被称为行地址。行地址加*改变该指针的性质,称为一级指针。
-
编程实现,使用行指针遍历二维数组?
同上,使用行指针遍历二维数组。
-