【C语言】——指针五:转移表与回调函数

这篇具有很好参考价值的文章主要介绍了【C语言】——指针五:转移表与回调函数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、转移表

1.1、转移表的定义

  
  在之前的学习中,我们学习了函数指针数组(详情请看【C语言】——指针四:字符指针与函数指针变量),在最后。我曾问到:函数指针数组有什么用呢?别急,本文给大家细细道来。
  
  函数指针数组常常被用在转移表中,那转移表是什么呢?
  
  转移表是一种数据结构,他用于根据输入值来确定需要执行的函数或操作,转移表通常是一个包含指针的数组,数组中每个元素包含着指向对应函数或操作的指针,通过查找对应的输入值进行索引,程序可以调用对应位置的函数或操作,从而实现通过输入值动态调度程序执行不同的功能
  
图示:

【C语言】——指针五:转移表与回调函数,C语言,c语言,开发语言,学习,算法,数据结构

  
  转移表的使用可以避免冗长的 i f − e l s e if-else ifelse 语句或 s w i t c h switch switch 语句,有效提高代码的可读性和维护性。通过利用转移表,程序可以根据输入值在常量时间内找到对应的操作或函数,并进行执行,而不需要逐个判断条件。转移表在实现分支逻辑较多、需要快速查找执行路径的情况下非常有用。
  
  不知道你懂了吗?如果此时的你还有点懵,我们举一些生活中的例子来加深理解吧。

  • 比如我们去餐厅吃饭,点菜时菜单就像是一个转移表,菜单上的每个菜,可看成转移表中的函数指针,每道菜对应这一个价格和烹饪方法,即函数定义。当我们选择后,餐厅通知厨师开始烹饪,即执行相关函数。总结下来,即:菜单就是转移表,通过菜名(输入值)来决定具体的烹饪操作(函数)
      
  • 另外,想象你玩一个游戏,根据不同的按键操作进行不同的动作,比如按下"A"键跳跃、按下"B"键攻击。游戏中的按键映射就可以看作是一个转移表,根据玩家的操作(输入值)执行相应的游戏动作(函数)。

  

1.2、简易计算器的一般实现

  
下面,我们来用一般方法来实现一个简易计算器:

#include<stdio.h>

int Add(int a, int b)
{
	return a + b;
}

int Sub(int a, int b)
{
	return a - b;
}

int Mul(int a, int b)
{
	return a * b;
}

int Div(int a, int b)
{
	return a / b;
}

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 x = 0, y = 0;
	int input = 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;
}

  

1.3、用转移表实现简易计算器

  
  虽然上述代码用 s w i t c h switch switch 语句实现了简易的计算器,但是可以发现,这段代码有许多重复的语句,太过冗余。那可以怎么改进呢?这时,我们就可以用函数指针数组实现一个转移表了。
  

int(*p[5])(int, int) = { 0,Add,Sub, Mul,Div };

  

  这里,我们创建一个函数指针数组作为转移表
  
  因为数组的下标是从 0 开始的,因此我们的首位放置 0往后各位置放置相应函数地址函数名就是函数地址),以便与前面的选择菜单一一对应

  

#include<stdio.h>

int Add(int a, int b)
{
	return a + b;
}

int Sub(int a, int b)
{
	return a - b;
}

int Mul(int a, int b)
{
	return a * b;
}

int Div(int a, int b)
{
	return a / b;
}

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 x = 0, y = 0;
	int input = 0;
	int ret = 0;

	int(*p[5])(int, int) = { 0,Add,Sub, Mul,Div };

	do
	{
		menu();

		printf("请选择:");
		scanf("%d", &input);


		if(input <= 4 && input >= 1)
		{
			printf("请输入要计算的两个数:");
			scanf("%d %d", &x, &y);
			int ret = p[input](x, y); 
			printf("运算结果是:%d\n", ret);
		}

		else if(0 == input)
		{
			printf("退出计算器\n");
		}

		else
		{
			printf("选择错误,请重新选择\n");
		}

	} while (input);

	return 0;
}

  
  

二、回调函数

  

2.1、回调函数的定义

  
  这里呢,介绍一个新概念,回调函数。
  
  回调函数是什么?回调函数就是一个通过函数指针调用的函数。
  
  如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,被调用的函数就是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的条件下,由另一方进行调用,用于对该条件或事件的响应。
  
我们通过简单的例子来理解一下:

#include<stdio.h>

void test1()
{
	printf("hello world\n");
}

void test2(void (*p)())
{
	(*p)();
}

int main()
{
	test2(test1);
	return 0;
}

  
  上述代码中, m a i n main main函数通过调用 t e s t 2 test2 test2 函数来调用 t e s t 1 test1 test1 函数,最终在屏幕上打印出 " h e l l o "hello "hello w o r l d " world" world"
  

2.2、用回调函数实现简易计算器

  
  了解了回调函数,那上面的简易计算器也可以通过回调函数来改进啦。
  
  我们发现,第一个版本的计算器中,选择不同的功能时, s w i t c h switch switch 语句太过冗余,那么我们可不可以将这部分封装成一个函数,再通过这个函数来调用运算函数呢?
  

【C语言】——指针五:转移表与回调函数,C语言,c语言,开发语言,学习,算法,数据结构

  
我们可以将他们封装成 c a l c calc calc 函数

void calc(int(*p)(int, int))
{
	int ret = 0;
	int x = 0, y = 0;
	printf("请输入要计算的两个数:");
	scanf("%d %d", &x, &y);
	ret = p(x, y);
    printf("运算结果是:%d\n", ret);
}

  
  这样,当我们进行不同的选择时,只需要将不同的运算函数指针传给 c a l c calc calc 函数就行了,省去了大量的重复代码。

#include<stdio.h>

int Add(int a, int b)
{
	return a + b;
}

int Sub(int a, int b)
{
	return a - b;
}

int Mul(int a, int b)
{
	return a * b;
}

int Div(int a, int b)
{
	return a / b;
}

void menu()
{
	printf("***************************\n");
	printf("***  1: Add     2: Sub  ***\n");
	printf("***  3: Mul     4: Div  ***\n");
	printf("***        0: exit      ***\n");
	printf("***************************\n");
}

//calc函数的定义
void calc(int(*p)(int, int))
{
	int ret = 0;
	int x = 0, y = 0;
	printf("请输入要计算的两个数:");
	scanf("%d %d", &x, &y);
	ret = p(x, y);
    printf("运算结果是:%d\n", ret);
}

int main()
{

	int input = 0;

	do
	{

		menu();
		printf("请选择:");
		scanf("%d", &input);


		switch (input)
		{

		case 1:
			calc(Add);//通过calc函数调用Add函数
			break;

		case 2:
			calc(Sub);//通过calc函数调用Sub函数
			break;

		case 3:
			calc(Mul);//通过calc函数调用Mul函数
			break;

		case 4:
			calc(Div);//通过calc函数调用Div函数
			break;

		case 0:
			printf("退出计算器\n");
			break;

		default:
			printf("选择错误,请重新选择\n");
			break;

		}
	} while (input);

	return 0;
}

  
  
  
  


  好啦,本期关于转移表与回调函数就介绍到这里啦,希望本期博客能对你有所帮助,同时,如果有错误的地方请多多指正,让我们在C语言的学习路上一起进步!文章来源地址https://www.toymoban.com/news/detail-843397.html

到了这里,关于【C语言】——指针五:转移表与回调函数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 函数指针和回调函数 以及指针函数

    函数指针(Function Pointer): 定义: 函数指针是指向函数的指针,它存储了函数的地址。函数的二制制代码存放在内存四区中的代码段,函数的地址它在内存中的开始地址。如果把函数的地址作为参数,就可以在函数中灵活的调用其它函数。 用途: 函数指针可以用来在运行

    2024年01月21日
    浏览(59)
  • 理解函数指针和回调函数

    指向函数的指针。比如: 理解函数指针的伪代码 比如,B把自己函数cbkFunc()的地址告诉A,A在运行过程中执行cbkFunc()。则 回调函数:指B的函数cbkFunc(); 注册回调函数:指B把函数cbkFunc()的地址告诉A; 回调:指A在运行过程中执行cbkFunc()。 无头文件.h 为了方便模块A和B写在了一

    2023年04月20日
    浏览(38)
  • C/C++面向对象(OOP)编程-回调函数详解(回调函数、C/C++异步回调、函数指针)

    本文主要介绍回调函数的使用,包括函数指针、异步回调编程、主要通过详细的例子来指导在异步编程和事件编程中如何使用回调函数来实现。 🎬个人简介:一个全栈工程师的升级之路! 📋个人专栏:C/C++精进之路 🎀CSDN主页 发狂的小花 🌄人生秘诀:学习的本质就是极致

    2024年02月03日
    浏览(39)
  • C生万物 | 剖析函数指针经典应用 —— 回调函数

    不懂函数指针的老铁可以先看看这篇文章【指针函数与函数指针】,上车,准备出发🚗 回调函数就是一个通过【函数指针】调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数

    2024年02月04日
    浏览(51)
  • 【再识C进阶2(中)】详细介绍指针的进阶——函数指针数组、回调函数、qsort函数

    💓作者简介: 加油,旭杏,目前大二,正在学习 C++ , 数据结构 等👀 💓作者主页:加油,旭杏的主页👀 ⏩本文收录在:再识C进阶的专栏👀 🚚代码仓库:旭日东升 1👀 🌹欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖        在这一篇博客中,我们要认识并理解 函数指

    2024年02月09日
    浏览(45)
  • 【C进阶】回调函数(指针进阶2,详解,小白必看)

    目录 6. 函数指针数组 6.1简单计算器 6.2函数指针数组实现计算器 7. 指向函数指针数组的指针(仅作了解即可) 8.回调函数 8.1关于回调函数的理解​编辑 8.1.1用回调函数改良简单计算器 8.2qsort库函数的使用 8.2.1冒泡排序 8.2.2qsort的概念 8.3冒泡排序思想实现qsort          这篇文

    2024年02月14日
    浏览(38)
  • C语言-指针进阶-qsort函数的学习与模拟实现(9.3)

    目录 思维导图: 回调函数 qsort函数介绍 模拟实现qsort 写在最后: 什么是回调函数? 回调函数是一个通过函数指针调用的函数。 将一个函数指针作为参数传递给一个函数,当这个指针被用来调用所指向函数时, 我们就将此称为回调函数。 在举例之前,我们先学习一个C语言

    2024年02月15日
    浏览(54)
  • 【云原生】k8s中Contrainer 生命周期回调/策略/指针学习

    个人主页: 征服bug-CSDN博客 kubernetes专栏: kubernetes_征服bug的博客-CSDN博客  目录 1 容器生命周期 2 容器生命周期回调/事件/钩子 3 容器重启策略 4 自定义容器启动命令 5 容器探针 1 容器生命周期 Kubernetes 会跟踪 Pod 中每个容器的状态,就像它跟踪 Pod 总体上的阶段一样。 你可

    2024年02月14日
    浏览(43)
  • Callback回调函数介绍(C语言)

    目录 1. 回调函数的定义 2. 为什么要用回调函数 3. 怎么用回调函数 3.1 怎么使用没有参数的回调函数 3.2 怎么使用带参数的回调函数 最近在工作中经常用到回调函数callback,总结一下。 先来看看维基百科对callback的解释:In computer programming, a callback is any executable code that is pass

    2024年02月02日
    浏览(52)
  • 【C语言】回调函数(qsort)与模拟实现

    何思何虑,居心当如止水;勿取勿忘,为学当如流水。— 出自《格言联璧·学问类》 解释:无思无虑,心境应当平静如水;不求冒进也不忘记,学业当如流水一般永无止境。 这篇博客我们将会理解回调函数这个概念,以及借用qsort帮助理解,并且最终用qsort的思路来实现冒泡

    2024年02月16日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包