6. 函数指针数组
数组是一个存放相同类型数据的存储空间,那我们已经学习了指针数组,
比如:
int *arr[10]; //数组的每个元素是int*
那要把函数的地址存到一个数组中,那这个数组就叫函数指针数组,那函数指针的数组如何定义呢?
int (*parr1[10])(); int *parr2[10](); int (*)() parr3[10];
答案是:parr1
parr1 先和 [] 结合,说明 parr1是数组,数组的内容是什么呢?
是 int (*)() 类型的函数指针。
int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } int main() { //存放函数指针的数组 - 函数指针数组 int (* pf[4])(int, int) = {Add, Sub, Mul, Div}; //0 1 2 3 int i = 0; for (i = 0; i < 4; i++) { int ret = pf[i](8, 4); printf("%d\n", ret); } return 0; }
函数指针数组的用途:转移表
例子:(计算器)
先写一个冗余的计算器
int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } //写一个计算器能完成整数的+-*/ //增加: << >> & | ^ && || // void menu() { printf("******************************\n"); printf("**** 1. add 2.sub *****\n"); printf("**** 3. mul 4.div *****\n"); printf("**** 0. exit *****\n"); printf("******************************\n"); } int main() { int input = 0; int x = 0; int y = 0; int ret = 0; do { menu(); printf("请选择:>"); scanf("%d", &input); switch (input) { case 1: printf("请输入两个操作数:>"); scanf("%d %d", &x, &y); ret = Add(x, y); printf("%d\n", ret); break; case 2: printf("请输入两个操作数:>"); scanf("%d %d", &x, &y); ret = Sub(x, y); printf("%d\n", ret); break; case 3: printf("请输入两个操作数:>"); scanf("%d %d", &x, &y); ret = Mul(x, y); printf("%d\n", ret); break; case 4: printf("请输入两个操作数:>"); scanf("%d %d", &x, &y); ret = Div(x, y); printf("%d\n", ret); break; case 0: printf("退出计算器\n"); break; default: printf("选择错误\n"); break; } } while (input); return 0; }
使用函数指针数组的实现:
int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } //写一个计算器能完成整数的+-*/ //增加: << >> & | ^ && || // void menu() { printf("******************************\n"); printf("**** 1. add 2.sub *****\n"); printf("**** 3. mul 4.div *****\n"); printf("**** 0. exit *****\n"); printf("******************************\n"); } int main() { int input = 0; int x = 0; int y = 0; int ret = 0; //转移表 - 函数指针的数组 int (*pfArr[])(int, int) = { NULL, Add, Sub, Mul, Div }; //0 1 2 3 4 do { menu(); printf("请选择:>"); scanf("%d", &input); if (input == 0) { printf("退出计算器\n"); break; } else if (input >= 1 && input <= 4) { printf("请输入两个操作数:>"); scanf("%d %d", &x, &y); ret = pfArr[input](x, y); printf("%d\n", ret); } else { printf("选择错误\n"); } } while (input); return 0; }
7. 指向函数指针数组的指针
指向函数指针数组的指针是一个 指针
指针指向一个 数组 ,数组的元素都是 函数指针 ;
如何定义?
void test(const char* str) { printf("%s\n", str); } int main() { //函数指针pfun void (*pfun)(const char*) = test; //函数指针的数组pfunArr void (*pfunArr[5])(const char* str); pfunArr[0] = test; //指向函数指针数组pfunArr的指针ppfunArr void (*(*ppfunArr)[5])(const char*) = &pfunArr; return 0; }
再举了一个例子:
int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int main() { int (*pf)(int, int) = Add; //函数指针数组 int (* pfArr[4])(int, int) = {Add, Sub}; // int (*(* ppfArr)[4])(int, int) = &pfArr;//ppfArr是一个指向函数指针数组的指针变量 return 0; }
8. 回调函数
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
拿一下刚刚的计算器代码来优化讲解一下回调函数:
#include <stdio.h> int Add(int x, int y)//回调函数 { return x + y; } int Sub(int x, int y)//回调函数 { return x - y; } int Mul(int x, int y)//回调函数 { return x * y; } int Div(int x, int y)//回调函数 { return x / y; } //写一个计算器能完成整数的+-*/ //增加: << >> & | ^ && || // void menu() { printf("******************************\n"); printf("**** 1. add 2.sub *****\n"); printf("**** 3. mul 4.div *****\n"); printf("**** 0. exit *****\n"); printf("******************************\n"); } void Calc(int(*pf)(int, int)) { int x = 0; int y = 0; int ret = 0; printf("请输入两个操作数:>"); scanf("%d %d", &x, &y); ret = pf(x, y); printf("%d\n", ret); } int main() { int input = 0; do { menu(); printf("请选择:>"); scanf("%d", &input); switch (input) { case 1: Calc(Add); break; case 2: Calc(Sub); break; case 3: Calc(Mul); break; case 4: Calc(Div); break; case 0: printf("退出计算器\n"); break; default: printf("选择错误\n"); break; } } while (input); return 0; }
此时代码上面标注的就是回调函数。
图片展示过程:
如果这份博客对大家有帮助,希望各位给恒川一个免费的点赞作为鼓励,并评论收藏一下,谢谢大家!!!
制作不易,如果大家有什么疑问或给恒川的意见,欢迎评论区留言。
下一期要用到sqort库函数来讲解回调函数,希望大家期待一下!