指针数组
1、学习目标
- 掌握指针数组的用法
- 总结与思考
2、指针数组
-
所谓指针数组是指由若干个具有相同存储类型和数据类型的指针变量构成的集合。
-
指针数组的一般说明形式:
- <存储类型> <数据类型> *<指针数组名> [<大小>]
- 指针数组名表示该指针数组的起始地址
-
声明一个指针数组
-
double * p[2] (指针数组), a[2] [3](二维数组);
把一维数组a[0]和a[1]的首地址分别赋予指针变量数组的数组元素p[0]和p[1]。
p[0]=a[0]; //等价p[0]= &a[0] [0]; p[0]指向了一维数组a[0]的第一个元素a[0] [0]
p[1]=a[1]; //等价p[1] = &a[1] [0]; p[1]指向了一维数组a[1]的第一个元素a[1] [0]
-
p[0]=a[0];p[1]=a[1];原理示意图:
-
示例:指针数组与一维数组的关系
#include <stdio.h> int main() { int * p[3]; int a[] = {3,6,1,9,10}; p[0] = a; p[1] = a + 1; p[2] = a + 3; //p[0],p[1],p[2]均为地址 printf("%d %d %d\n", a[0], a[1], a[3]); printf("%d %d %d\n", *(p[0]), *(p[1]), *(p[2])); //[]的优先级高于* 所以()可以省略 return 0; }
运行结果:
$ ./app 3 6 9 3 6 9
指针数组与二维数组的关系
#include <stdio.h> int main() { int a[2][3] = {{1,4,6},{12,9,7}}; int * p[2]; p[0] = a[0];//&a[0][0] p[1] = a[1];//&a[1][0] printf("%d\n", a[0][1]); printf("%d\n", *(a[0]+1));//加*取值 printf("%d\n", *(p[0]+1));//一级指针加1是移动一个数(列) printf("%d\n", *(p[1]+2)); return 0; }
运行结果:
$ ./app 4 4 4 7
示意图:
-
3、程序举例
-
编程:利用指针数组处理一个二维数组,要求求出二维数组所有元素的和。
(1)指针数组加1,移动多少字节?
#include <stdio.h> int main() { int a[2][3] = {{1,4,6},{12,9,7}}; int * p[2] = {a[0], a[1]}; printf("%p %p\n", p[0], a[0]); printf("%p %p\n", p[1], a[1]); //p[0]指向a[0],p[1]指向a[1] return 0; }
运行结果:
$ ./app 0x7ffeba244cc0 0x7ffeba244cc0 0x7ffeba244ccc 0x7ffeba244ccc//12个字节3*4
(2)访问第i行第j列。
#include <stdio.h> int main() { int a[2][3] = {{1,4,6},{12,9,7}}; int * p[2] = {a[0], a[1]}; int i, j; // printf("%p %p\n", p[0], a[0]); // printf("%p %p\n", p[1], a[1]); for(i = 0; i < 2; i++){ for(j = 0; j < 3; j++) printf("%d %d %d", a[i][j], *(a[i]+j), *(p[i]+j)); // printf("%d %d ", *(*(a+i) + j), *(*(p+i) + j)); //拆开下标 puts(""); } return 0; }
运行结果:
$ ./app 1 1 1 4 4 4 6 6 6 12 12 12 9 9 9 7 7 7
(3)求和
#include <stdio.h> int main() { int a[2][3] = {{1,4,6},{12,9,7}}; int * p[2] = {a[0], a[1]}; int i, j, sum = 0; // printf("%p %p\n", p[0], a[0]); // printf("%p %p\n", p[1], a[1]); for(i = 0; i < 2; i++){ for(j = 0; j < 3; j++) sum += *(p[i]+j); } printf("sum = %d\n", sum); return 0; }
运行结果:
$ ./app sum = 39
4、总结与思考
-
主要介绍了指针数组的用法,包括声明,初始化,赋值及指针数组如何访问二维数组等。
-
思考
-
如何计算指针数组占用的内存空间?
#include <stdio.h> int main() { int a[2][3] = {{1,4,6},{12,9,7}}; int * p[2] = {a[0], a[1]}; int i, j, sum = 0; printf("total: %d\n", sizeof(p)); return 0; }
运行结果:指针在64位机中长度占8字节,int *p[2]中有两个长度为8字节的地址
$ ./app total: 16
-
指针数组名加1,移动多少字节?
- *(p+1):走了一行; * (p+1)+1走了一列
- 字节数由指针数组指向的数组内容决定,见“程序举例(1)”
-
指针数组名相当于什么样的指针?
- 指针数组名就是元素地址相当于一级指针取地址就是二级指针,故指针数组名相当于二级指针
- “数据类型 * q ” 本身就是一个指针,而它的数据类型是int * 也是一个指针,故称为二级指针。
-