开篇应用
你是否想过用代码实现计算器功能?
请看效果!!!
计算器的实现
加法:Add 减法:Sub
乘法:Mul 除法:Div
方式一:函数
说明:利用函数,do...while...循环,switch...case...等语句实现
x 和 y 分别代表两个要输入的数
加法举例
应用举例(菜单)
void menu() { printf("*****************************\n"); printf("***********0.退出************\n"); printf("******1.加法 2.减法********\n"); printf("******3.乘法 4.除法********\n"); printf("*********其他.选择错误*******\n"); printf("*****************************\n"); }
函数
int Add(int x, int y) { return x + y; }
主函数
int main() { int n = 0; int x = 0, y = 0; do { menu(); printf("请选择-->"); scanf("%d", &n); switch (n) { case 1: printf("请输入要相加的两个数(两个数之间以空格隔开):"); scanf("%d %d", &x, &y); Add(x, y); printf("%d\n", Add(x, y)); break; } } while (n); return 0; }
总代码
void menu() { printf("*****************************\n"); printf("***********0.退出************\n"); printf("******1.加法 2.减法********\n"); printf("******3.乘法 4.除法********\n"); printf("*********其他.选择错误*******\n"); printf("*****************************\n"); } 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 n = 0; int x = 0, y = 0; do { menu(); printf("请选择-->"); scanf("%d", &n); switch (n) { case 0: break; case 1: printf("请输入要相加的两个数(两个数之间以空格隔开):"); scanf("%d %d", &x, &y); Add(x, y); printf("%d\n", Add(x, y)); break; case 2: printf("请输入要相减的两个数(两个数之间以空格隔开):"); scanf("%d %d", &x, &y); Sub(x, y); printf("%d\n", Sub(x, y)); break; case 3: printf("请输入要相乘的两个数(两个数之间以空格隔开):"); scanf("%d %d", &x, &y); Mul(x, y); printf("%d\n", Mul(x, y)); break; case 4: printf("请输入要相除的两个数(两个数之间以空格隔开):"); scanf("%d %d", &x, &y); Div(x, y); printf("%d\n", Div(x, y)); break; default: printf("选择错误,请重新选择\n"); break; } } while (n); return 0; }
方式二:函数指针
函数指针的介绍
函数指针:顾名思义,首先它是一个指针,一个指向函数的指针,在内存空间中存放的是函数的地址;
使用介绍:
函数的返回类型(*指针名)(函数的参数列表类型)//定义
返回类型 和 参数类型 与 函数 相同
例如:加法举例
int Add(int x, int y) { return x + y; } int main() { int (*pf)(int, int) = Add; return 0; }
进一步探讨:
请看代码:
int Add(int x, int y) { return x + y; } int main() { printf("%p\n", &Add); printf("%p\n", Add); return 0; }
我们知道,数组名 等于 数组首元素地址
思考一下:加了 & 和不加 & ,输出的两个结果有什么区别呢?
注意: %p 是打印地址的
很明显,我们看到的结果是一样的;
由此我们可以得到结论 :
函数名 等于 函数地址.
一张图看懂用函数指针替换函数
还是用加法举例
这时就会有人有疑问了,函数指针从字母来论比函数都多,还不如直接写函数呢?
No , No , No ! 其实并不然,你看到的只是局部,格局打开 !
函数指针数组的用途:转移表
函数指针数组示例
int arr[10] = { 0 };
int(*parr)[10] = &arr;
函数指针数组的讲解
用转移表实现计算器
总代码
void menu() { printf("*****************************\n"); printf("***********0.退出************\n"); printf("******1.加法 2.减法********\n"); printf("******3.乘法 4.除法********\n"); printf("*********其他.选择错误*******\n"); printf("*****************************\n"); } 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 n = 0, x = 0, y = 0; do { menu(); scanf("%d", &n); int (*parr[])(int, int) = { NULL,Add,Sub,Mul,Div }; //n的输入分别对应 : 0 1 2 3 4 if (n == 0) { printf("已退出此应用\n"); break; } if (n >= 1 && n <= 4) { printf("请输入的两个操作数(两个数之间以空格隔开):"); scanf("%d %d", &x, &y); //函数指针数组的使用 int ret = parr[n](x, y); printf("%d\n", ret); } else { printf("选择错误,请重新选择\n"); } } while (n); return 0; }
使用完转移表后,代码比简单的函数要少了些许,但还不满足
我们发现在简单函数实现计算器时发现,每列出不同功能情况时,总会有很多相同的冗杂在一起。
接下来我们将介绍回调函数把代码优化一下!
方式三:回调函数
概念
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
这段话很长,我用一张图说明
回调函数和简单函数的比较
总代码
void menu() { printf("*****************************\n"); printf("***********0.退出************\n"); printf("******1.加法 2.减法********\n"); printf("******3.乘法 4.除法********\n"); printf("*********其他.选择错误*******\n"); printf("*****************************\n"); } 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 calc(int (*pf)(int, int)) { int x = 0, y = 0, ret = 0; printf("请输入的两个操作数(两个数之间以空格隔开):"); scanf("%d %d", &x, &y); ret = pf(x, y); printf("%d\n", ret); } int main() { int n = 0, x = 0, y = 0; do { menu(); scanf("%d", &n); switch (n) { case 0: printf("已退出此应用\n"); break; case 1: calc(Add); break; case 2: calc(Sub); break; case 3: calc(Mul); break; case 4: calc(Div); break; default: printf("选择错误,请重新选择\n"); break; } } while (n); return 0; }
回调函数一图KO