魔法指针 之 函数指针 回调函数

简介: 魔法指针 之 函数指针 回调函数

开篇应用


你是否想过用代码实现计算器功能?

请看效果!!!


计算器的实现


加法:Add    减法:Sub

乘法:Mul    除法:Div

方式一:函数

说明:利用函数,do...while...循环,switch...case...等语句实现

xy 分别代表两个要输入的数

加法举例

应用举例(菜单)
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

目录
相关文章
|
2月前
|
C++
指针中的回调函数与qsort的深度理解与模拟
本文详细介绍了回调函数的概念及其在计算器简化中的应用,以及C++标准库函数qsort的原理和使用示例,包括冒泡排序的模拟实现。
22 1
|
7月前
指针(5)---回调函数
指针(5)---回调函数
32 0
|
2月前
|
存储
一篇文章了解区分指针数组,数组指针,函数指针,链表。
一篇文章了解区分指针数组,数组指针,函数指针,链表。
21 0
|
7月前
|
编译器 C语言
C语言进阶⑪(指针上)(知识点和对应练习)回调函数模拟实现qsort。(下)
C语言进阶⑪(指针上)(知识点和对应练习)回调函数模拟实现qsort。
47 0
|
4月前
|
存储 程序员 C语言
指针的高级应用:指针数组、数组指针、函数指针等。
指针的高级应用:指针数组、数组指针、函数指针等。
151 0
|
6月前
|
C语言
指针进阶(回调函数)(C语言)
指针进阶(回调函数)(C语言)
|
6月前
|
存储 C语言 C++
指针进阶(函数指针)(C语言)
指针进阶(函数指针)(C语言)
|
6月前
|
C语言
【C语言】:详解函数指针变量,函数指针数组及转移表
【C语言】:详解函数指针变量,函数指针数组及转移表
74 2
|
7月前
|
算法 搜索推荐 C语言
c函数指针与回调函数
c函数指针与回调函数
51 2
|
6月前
|
C语言
C语言中的函数指针、指针函数与函数回调
C语言中的函数指针、指针函数与函数回调