1.指针函数的概念
1、概念:
- 知识点:
- 举例:
2、指针函数为啥这么定义?(通用的判别方法):
- 指针函数是个指针,所以函数名a先和形参列表结合,表明a是一个函数,然后再和int *结合,表明函数的返回值是int*类型的数据。如果给*a两边加上小括号,那么就成函数指针了。
正确的定义方法: int *a(int x, int y); 错误的定义方法: int (*a)(int x, int y);
- 适用于变量、指针、函数的类型判别方法:地位从高到底
- 找到变量名,若没有变量名,找到最里面的结构
- 向右看,读出看到的东西,不要跳过括号
- 向左看,读出看到的东西,不要跳过括号
- 若有括号,跳出第一层括号
- 重复上述过程,直到读出最终的类型
习题1:
- 思路:通过指针函数找出二维数组某一行的首地址,然后把这一行当做一维数组打印。
f1. 封装返回二维数组指定行地址的API: int* getRowAddress(int num, int (*parr2)[4]); 形参是行号、保存二维数组父地址的数组指针变量parr2 f1.1 用数组指针偏移的方法将子数组名赋值给一个一维指针p:int *p = *(parr2+num); f1.2 返回一维指针p,p就代表第num行的首地址 1. 定义并初始化一个二维数组scores[3][4] 2. 输入学生的序号,也就是二维数组的行号num 3. 调用API1. 从二维数组arr中获取第num行的首地址,保存在一个一维指针prow中: int *prow = getRowAddress(num, scores); 4. for循环,代表列号的循环变量j从0开始,<4 时,进入循环 4.1 通过指针偏移间接访问二维数组第num行的所有元素: *(prow+j) 也就是第num个学生的所有成绩
- 代码:
#include <stdio.h> int* getRowAddress(int num, int (*parr2)[4]); int main(int argc, char const *argv[]) { int num; //代表第num个学生 int scores[3][4] ={ //三个学生,四门课程 {59,78,90,88}, {80,82,61,85}, {79,55,94,80}}; int *prow; //用int*型指针保存二维数组第num行的首地址 puts("请输入学生序号(0~2)"); scanf("%d", &num); prow = getRowAddress(num, scores); //通过指针函数获取第num行学生成绩的首地址 for(int j=0; j<4; j++){ printf("%d ", *(prow+j)); //通过指针偏移间接调用数组元素 } return 0; } int* getRowAddress(int num, int (*parr2)[4]) { int *p; p = *(parr2+num); return p; }
习题2:
- 思路:在习题1的基础上对学生序号num进行遍历,使用回调来的行地址进行偏移,间接访问二维数组。
- 代码:
#include <stdio.h> int *getRowAddress(int num, int (*parr2)[4]); int main(int argc, char const *argv[]) { int num; int scores[3][4] = { {59, 78, 90, 88}, {80, 82, 61, 85}, {79, 55, 94, 80}}; int *prow; for (num = 0; num < 3; num++){ prow = getRowAddress(num, scores); for (int j = 0; j < 4; j++){ if( *(prow+j)<60 ){ printf("序号为%d的学生有不及格成绩\n", num); } } } return 0; } int *getRowAddress(int num, int (*parr2)[4]) { int *p; p = *(parr2 + num); return p; }