1.定义一个数组指针变量指向二维数组名
1、知识点:
- 二维数组名是地址常量,它不是地址的地址,它是一个数组指针类型的数据。
- 定义数组指针时,要保证二维数组的类型和数组指针的类型一致,这里的类型关注两点:①二维数组的第二维长度与数组指针所指向的数组的元素个数是否一致、②二维数组元素的数据类型和数组指针前面的数据类型是否一致,比如int arr[3][4]; 必须用int (*p)[4]; 匹配
2、两种方式:
- 将第0个子数组名取地址赋值给数组指针
int arr[3][4] = {{1,3,5,7},{9,11,13,15},{17,19,21,23}}; int (*parr2)[4] = &arr[0];
- 将父数组名赋值给数组指针
int arr[3][4] = {{1,3,5,7},{9,11,13,15},{17,19,21,23}}; int (*parr2)[4] = arr;
2.通过数组指针偏移间接访问二维数组的每一个元素
1、知识点:4.二维数组(父数组与子数组)。
2、标准写法:数组指针偏移取星花。
#include <stdio.h>
int main(int argc, char const *argv[])
{
int i, j;
int arr[3][4] = {{1,3,5,7},{9,11,13,15},{17,19,21,23}};
int (*parr2)[4] = arr;
for(i=0; i<3; i++){
for(j=0; j<4; j++){
printf("%d ", *(*(parr2+i)+j)); //数组指针偏移取星花法间接访问二维数组元素
}
putchar('\n');
}
return 0;
}
3、见怪不怪的写法:
- 数组指针下标法:把数组指针当做二维数组名,然后下标法访问,这种方法比较直观。
#include <stdio.h> int main(int argc, char const *argv[]) { int i, j; int arr[3][4] = {{1,3,5,7},{9,11,13,15},{17,19,21,23}}; int (*parr2)[4] = arr; for(i=0; i<3; i++){ for(j=0; j<4; j++){ printf("%d ", parr2[i][j]); //数组指针下标法间接访问二维数组元素 } putchar('\n'); } return 0; }
- 二维数组名当做数组指针来用:略,前面已经讲过。
3.习题(函数形参接收二维数组名)
1、代码心得:
- 有了数组指针之后,我们在用二维数组作为函数的参数的时候,既然已经知道了二维数组的名字就是一个地址常量,那么不要再用假数组的方式定义形参了,要用数组指针来保存这个地址常量。
- 函数的形参如果是指针,我们要养成一个命名习惯:int *parr2,前面加个p代表指针变量parr保存的是arr的地址。
- 函数中,为了符合人的阅读习惯,我们一般用数组指针下标法来间接访问二维数组元素。
习题1:封装初始化和打印二维数组的API
- 思路:
f1. 封装初始化二维数组的API:void initArrDouble(int (*parr2)[4] int row, int column); 形参分别是保存二维数组的数组指针,行数,列数 f1.1 for循环,表示数组行下标的循环变量i从0开始,<row 时,进入循环 f1.1.1 for循环,表示数组列下标的循环变量j从0开始,<column 时,进入循环 f1.1.1.1 输入二维数组元素,通过数组指针下标法间接访问二维数组元素 f2. 封装打印二维数组的API:void printArrDouble(int (*parr2)[4], int row, int column); f2.1 for循环,表示数组行下标的循环变量i从0开始,<row 时,进入循环 f2.1.1 for循环,表示数组列下标的循环变量j从0开始,<column 时,进入循环 f1.1.1.1 打印数组元素,通过数组指针下标法间接访问二维数组元素 f2.1.2 换行 1. 定义一个二维数组arr 2. 用sizeof运算符获取二维数组的行数 3. 用sizeof运算符获取二维数组的列数 4. 用API1. 初始化二维数组 5. 用API2. 打印二维数组
- 代码:
#include <stdio.h> void initArrDouble(int (*parr2)[4], int row, int column); void printArrDouble(int (*parr2)[4], int row, int column); int main(int argc, char const *argv[]) { int arr[3][4]; int rowOfArr = sizeof(arr) / sizeof(arr[0]); int columnOfArr = sizeof(arr) / rowOfArr / sizeof(arr[0][0]); initArrDouble(arr, rowOfArr, columnOfArr); printArrDouble(arr, rowOfArr, columnOfArr); return 0; } void initArrDouble(int (*parr2)[4], int row, int column) { int i, j; for(i=0; i<row; i++){ for(j=0; j<column; j++){ printf("请输入第%d行,第%d列的数据\n", i+1, j+1); scanf("%d", &parr2[i][j]); } } } void printArrDouble(int (*parr2)[4], int row, int column) { int i, j; for(i=0; i<row; i++){ for(j=0; j<column; j++){ printf("%-4d", parr2[i][j]); } putchar('\n'); } }
习题2:封装获取二维数组第i行第j列元素值的API
- 思路:
f1. 封装获取二维数组第i行第j列元素值的API: int getData(int (*parr2)[4], int ihang, int jlie); f1.1 返回第i行第j列的元素,用数组指针下标法间接访问二维数组元素 1. 定义并初始化一个二维数组 2. 输入行号i和列号j 3. 打印API. 的返回值
- 思路:
#include <stdio.h> void initArrDouble(int (*parr2)[4], int row, int column); int getData(int (*parr2)[4], int ihang, int jlie); int main(int argc, char const *argv[]) { int arr[3][4]; int rowOfArr = sizeof(arr) / sizeof(arr[0]); int columnOfArr = sizeof(arr) / rowOfArr / sizeof(arr[0][0]); int i, j; initArrDouble(arr, rowOfArr, columnOfArr); puts("请输入行号和列号(从0开始)"); scanf("%d %d", &i, &j); printf("第%d行,第%d列的元素是%d\n", i, j, getData(arr, i, j)); return 0; } void initArrDouble(int (*parr2)[4], int row, int column) { int i, j; for(i=0; i<row; i++){ for(j=0; j<column; j++){ printf("请输入第%d行,第%d列的数据\n", i+1, j+1); scanf("%d", &parr2[i][j]); } } } int getData(int (*parr2)[4], int ihang, int jlie) { return parr2[ihang][jlie]; }