【嵌入式C快捷键设计】表驱动法实现

表驱动法的优势

这种设计实现了数据驱动的编程模式,将配置信息(快捷键映射)与执行逻辑分离,是嵌入式系统中实用的设计模式。具有维护性好、代码复用高、拓展性好等优点。

表驱动法的原理

将程序逻辑从代码转移到数据,通过查询数据表来决定程序行为,而不是通过复杂的控制逻辑。

表驱动法的核心原理是:通过数据配置来代替硬编码的逻辑判断,利用函数指针机制实现动态调用。

案例实战

cpp 复制代码
#include <stdio.h>
#include <string.h>
#include <stdint.h>

// 类型定义
typedef int32_t (*T_SHORTCUT_CALLBACK)(void);

#define SHORTCUT_MAX_ID_LEN 20
#define SHORTCUT_END_STR "end"

// 快捷键列表结构体
typedef struct {
	char id[SHORTCUT_MAX_ID_LEN + 1];
	T_SHORTCUT_CALLBACK cb;
	const char *description;  // 添加描述信息便于演示
} T_SHORTCUT_LIST;

// 定义返回码
typedef enum {
	eMENU_RESULT_SUCCESS = 0,
	eMENU_RESULT_FAIL = -1
} menu_result_t;

// 模拟权限验证函数
int app_is_second_user_verify(void) {
	return 0; // 假设总是有权限
}


void app_menu_exit_flag_clear(void) {
	printf("清理菜单退出标志\n");
}

// 具体的快捷键处理函数
int32_t save_function(void) {
	printf("执行保存操作...\n");
	printf("文件保存成功!\n");
	return eMENU_RESULT_SUCCESS;
}

int32_t print_function(void) {
	printf("执行打印操作...\n");
	printf("文档打印完成!\n");
	return eMENU_RESULT_SUCCESS;
}

int32_t help_function(void) {
	printf("   显示帮助信息:\n");
	printf("   save  - 保存文件\n");
	printf("   print - 打印文档\n");
	printf("   help  - 显示帮助\n");
	printf("   time  - 显示时间\n");
	printf("   exit  - 退出程序\n");
	return eMENU_RESULT_SUCCESS;
}

int32_t time_function(void) {
	printf("  当前时间: 2024-01-01 12:00:00\n");
	return eMENU_RESULT_SUCCESS;
}

int32_t exit_function(void) {
	printf("  感谢使用,再见!\n");
	return eMENU_RESULT_SUCCESS;
}

// 快捷键映射表
static const T_SHORTCUT_LIST app_shortcut_list[] = {
	{"save",  save_function,  "保存文件"},
	{"print", print_function, "打印文档"},
	{"help",  help_function,  "显示帮助"},
	{"time",  time_function,  "显示时间"},
	{"exit",  exit_function,  "退出程序"},
	{SHORTCUT_END_STR, NULL, "结束标记"}  // 必须放在最后!
};

// 快捷键处理函数
int8_t app_shortcut_handle(const char *key_buff) {
	uint16_t i = 0;

	printf("\n   正在查找快捷键: '%s'\n", key_buff);

	while(1) {


		// 检查是否匹配当前快捷键
		if(strcmp(app_shortcut_list[i].id, key_buff) == 0) {
			printf("  找到匹配的快捷键: %s -> %s\n",
			       app_shortcut_list[i].id, app_shortcut_list[i].description);


			// 执行回调函数
			printf("  开始执行回调函数...\n");
			int32_t ret = app_shortcut_list[i].cb();

			printf("  函数执行结果: %d\n", ret);
			return ret;
		}
		// 检查是否到达列表末尾
		else if(strcmp(app_shortcut_list[i].id, SHORTCUT_END_STR) == 0) {
			printf("  未找到匹配的快捷键: '%s'\n", key_buff);
			printf("  可用命令: save, print, help, time, exit\n");
			return eMENU_RESULT_FAIL;
		}

		i++;
	}
}

// 显示欢迎信息
void show_welcome(void) {
	printf("=====================================\n");
	printf("  表驱动法快捷键演示程序\n");
	printf("=====================================\n");
	printf("这是一个演示表驱动法处理快捷键的示例\n");
	printf("使用 scanf 接收用户输入\n\n");
}

// 显示快捷键列表
void show_shortcut_list(void) {
	printf("  可用的快捷键列表:\n");
	printf("-----------------------------\n");

	int i = 0;
	while(strcmp(app_shortcut_list[i].id, SHORTCUT_END_STR) != 0) {
		printf("  %-8s - %s\n",
		       app_shortcut_list[i].id,
		       app_shortcut_list[i].description);
		i++;
	}
	printf("-----------------------------\n");
}

int main(void) {
	char input[SHORTCUT_MAX_ID_LEN + 1];

	show_welcome();
	show_shortcut_list();

	// 主循环
	while(1) {
		printf("\n    请输入快捷键 (输入 exit 退出): ");

		// 使用scanf接收输入
		if(scanf("%20s", input) != 1) {
			printf("  输入错误,请重新输入\n");
			while(getchar() != '\n'); // 清空输入缓冲区
			continue;
		}

		// 处理快捷键
		int8_t result = app_shortcut_handle(input);

		if(strcmp(input, "exit") == 0) {
			break; // 退出程序
		}

		if(result == eMENU_RESULT_FAIL) {
			printf("快捷键处理失败\n");
		}
	}

	printf("\n=====================================\n");
	printf("   程序正常结束\n");
	printf("=====================================\n");

	return 0;
}
  • typedef:用于定义新类型的关键字。

  • int32_t:函数的返回值类型,通常是一个32位有符号整数(需要包含stdint.h头文件)。

  • (*T_SHORTCUT_CALLBACK)T_SHORTCUT_CALLBACK是一个指针,指向函数。

  • (void):函数的参数列表,这里表示没有参数。

所以,这个定义之后,我们可以使用T_SHORTCUT_CALLBACK来声明一个函数指针变量,该变量可以指向任何返回值类型为int32_t且无参数的函数。

相关推荐
Meteors.9 小时前
23种设计模式——外观模式(Facade Pattern)详解
设计模式·外观模式
胖虎19 小时前
iOS中的设计模式(九)- 外观模式 用外观模式点一份外卖:Swift 实战讲解
设计模式·外观模式
czy87874759 小时前
用C语言实现外观模式
c语言·外观模式
一匹电信狗9 小时前
【LeetCode_160】相交链表
c语言·开发语言·数据结构·c++·算法·leetcode·stl
小龙报10 小时前
《算法每日一题(1)--- 连续因子》
c语言·开发语言·c++·windows·git·算法·visual studio
yuuki23323310 小时前
【C语言】程序的编译和链接(基础向)
c语言·后端
第七序章10 小时前
【C + +】红黑树:全面剖析与深度学习
c语言·开发语言·数据结构·c++·人工智能
Asort11 小时前
JavaScript设计模式(十六)——迭代器模式:优雅遍历数据的艺术
前端·javascript·设计模式
昨天的猫11 小时前
原来我们写的单例还存在缺陷~~
设计模式
Tiny_React11 小时前
智能体设计模式-CH13:人类参与环节(Human-in-the-Loop)
设计模式