完整教程:《彻底理解C语言指针全攻略(5)--指针和函数专题》

指针和函数专题


小龙报:个人主页
❄️个人专栏:《C语言》《算法》KelpBar海带Linux智慧屏项目

永远相信美好的事情即将发生

在这里插入图片描述


前言

继上篇文章后这篇文章将继续为大家分享指针的相关知识,本篇主要是指针和函数相关的知识点,让我们向着更优秀的自己出发go!


一、函数指针变量

4.1 函数指针变量的创建

函数指针变量应该是⽤来存放函数地址的,未来通过地址能够调⽤函数的。

#include <stdio.h>
  void test()
  {
  printf("hehe\n");
  }
  int main()
  {
  printf("test:  %p\n", test);
  printf("&test: %p\n", &test);
  return 0;
  }

运行结果:
在这里插入图片描述
确实打印出来了地址,所以函数是有地址的,函数名就是函数的地址,当然也可以通过。&函数名的式获得函数的地址。
如果我们要将函数的地址存放起来,就得创建函数指针变量咯,函数指针变量的写法其实和数组指针非常类似。

int Add(int x, int y)
{
return x + y;
}
int(*pf3)(int, int) = Add;
int(*pf3)(int x, int y) = &Add;//x和y写上或者省略都是可以的

函数指针类型解析:
在这里插入图片描述

4.2 函数指针变量的使用

例.通过函数指针调⽤指针指向的函数

#include <stdio.h>
  int Add(int x, int y)
  {
  return x + y;
  }
  int main()
  {
  int(*pf3)(int, int) = Add;
  printf("%d\n", (*pf3)(2, 3));  //方式一
  printf("%d\n", pf3(3, 5)); //方式二
  return 0;
  }

运行结果:
在这里插入图片描述

二、 typedef 关键字

typedef 是⽤来类型重命名的,可以将复杂的类型,简单化。

2.1类型重命名

例:

typedef unsigned int uint;  //将unsigned int 重命名为uint

2.2指针类型重命名

例:

typedef int* ptr_t;

2.3数组指针类型重命名

例:

typedef int(*parr_t)[5]; //新的类型名必须在*的右边

2.4函数指针类型的重命名

例:

typedef void(*pfun_t)(int);//新的类型名必须在*的右边

三、 函数指针数组

创建方式:

int (*parr1[3])();

解析: parr1 先和[] 结合,说明parr1是数组,数组的内容是什么呢?是int (*)() 类型的函数指针。

四、转移表

函数指针数组的⽤途:转移表
举例:计算器的⼀般实现

#include <stdio.h>
  void menu()
  {
  printf("*************************\n");
  printf("  1:add           2:sub  \n");
  printf("  3:mul           4:div  \n");
  printf("  0:exit                 \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 x, y;
  int input;
  int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //转移表
  do
  {
  menu(); //菜单
  printf("请选择:");
  scanf("%d", &input);
  if (input >= 1 && input <= 4)
  {
  printf("请输入两个操作数: ");
  scanf(" %d %d", &x, &y);
  int ret = p[input](x, y);
  printf("%d\n",ret);
  }
  else if (input == 0)
  printf("退出计算器\n");
  else
  printf("输⼊有误\n");
  } while (input);
  return 0;
  }

运行结果:
在这里插入图片描述

五 、什么是回调函数

5.1回调函数的概念

回调函数就是⼀个通过函数指针调⽤的函数
如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数时,被调⽤的函数就是回调函数。回调函数不是由该函数的实现⽅直接调⽤,⽽是在特定的事件或条件发⽣时由另外的⼀⽅调⽤的,⽤于对该事件或条件进⾏响应。
例:

int Add(int x, int y)//这里的Add就是回调函数
{
return x + y;
}
void test(int(*pf)(int, int))
{
int r = pf(10, 20);
printf("%d\n", r);
}
int main()
{
test(Add);
return 0;
}

图解:
在这里插入图片描述

5.2使用回调函数改造计算器程序

#include <stdio.h>
  void menu()
  {
  printf("*************************\n");
  printf("  1:add           2:sub  \n");
  printf("  3:mul           4:div  \n");
  printf("  0:exit                 \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(*p)(int x, int y))
  {
  int ret = 0;
  int x,y;
  printf("请输入两个操作数: ");
  scanf("%d %d", &x, &y);
  ret = p(x, y);
  printf("%d\n", ret);
  }
  int main()
  {
  int x, y;
  int input;
  do
  {
  menu(); //菜单
  printf("请选择:");
  scanf("%d", &input);
  switch (input)
  {
  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");
  }
  } while (input);
  return 0;
  }

运行结果:
在这里插入图片描述
图解:

在这里插入图片描述
总结:
回调函数的功能:可以把调用的函数的地址以参数形式传递过去使用函数指针接收,函数指针指向什么函数就调用什么函数

六、总结—每日励志时刻

在这里插入图片描述

posted @ 2025-11-11 12:50  clnchanpin  阅读(98)  评论(0)    收藏  举报