【嵌入式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且无参数的函数。

相关推荐
润 下3 小时前
C语言——深入理解函数声明定义和调用访问
c语言·开发语言·经验分享·笔记·程序人生·其他
庸人自扰614 小时前
常见设计模式讲解
设计模式
bkspiderx5 小时前
C++设计模式之行为型模式:解释器模式(Interpreter)
c++·设计模式·解释器模式
范纹杉想快点毕业5 小时前
单片机开发中的队列数据结构详解,队列数据结构在单片机软件开发中的应用详解,C语言
c语言·数据库·stm32·单片机·嵌入式硬件·mongodb·fpga开发
坚持编程的菜鸟6 小时前
LeetCode每日一题——有效的字母异位词
c语言·算法·leetcode
小糖学代码6 小时前
STL的list模拟实现(带移动构造和emplace版本)
c语言·数据结构·c++·windows·list
王嘉俊9257 小时前
Qt 入门:构建跨平台 GUI 应用的强大框架
c语言·开发语言·c++·qt·入门·cpp
文心快码BaiduComate7 小时前
文心快码已接入GLM-4.6模型
前端·后端·设计模式
snowbitx8 小时前
一篇文章彻底搞懂前端架构层面分层设计
前端·设计模式·前端框架