3

编程模式-表驱动编程 - 大橙子疯

 1 year ago
source link: https://www.cnblogs.com/const-zpc/p/16364415.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

编程模式-表驱动编程

        刚开始编程时,往往会碰到一些根据不同条件执行不同功能的情况,通常都是采用if-else或者switch-case的方式,如果有很多的情况需要区分,则会有很多的 else if 或者case的代码处理,整个功能实现完成后,一看代码可能会有很多的else if 或者 case,为了避免这种情况,本编介绍一种开发方法--表驱动方法。

        表驱动方法是一种使你可以在表中查找信息,而不必用逻辑语句(if 或 case)来把他们找出来的方法。事实上,任何信息都可以通过表来挑选。在简单的情况下,逻辑语句往往更简单而且更直接。但随着逻辑链的复杂,表就变得越来越富于吸引力了。表驱动编程的意义在于逻辑与数据的分离。

可以简单的理解的就是用同样的方式处理不同的数据,表驱动方法具有以下特点:

  • 可读性强,数据处理流程一目了然。
  • 便于维护,只需要增、删数据索引和方法就可以实现功能。
  • 精简代码,降低圈复杂度。减少 if-else、switch-case 使用。
  • 在一定程度上可以提升程序运行速度。

首先,看一个简单的例子,没有采用表驱动方法的代码,根据输入的数字得到字符串。

void GetTimeString(int weak, char *pszTime)
{
    if (weak == 1)
    {
        sprintf(pszTime, "星期一");
    }
    else if (weak == 2)
    {
        sprintf(pszTime, "星期二");
    }
    else if (weak == 3)
    {
        sprintf(pszTime, "星期三");
    }
    else if (weak == 4)
    {
        sprintf(pszTime, "星期四");
    }
    else if (weak == 5)
    {
        sprintf(pszTime, "星期五");
    }
    else if (weak == 6)
    {
        sprintf(pszTime, "星期六");
    }
    else if (weak == 7)
    {
        sprintf(pszTime, "星期日");
    }
    else
    {
        sprintf(pszTime, "未知");
    }
}

采用表驱动方法后,代码得到精简,可读性增强(if-else过多会导致屏幕不够一眼看的),且在一定程度上提高了程序运行速度(若是 7 则不需要多次if判断)

void GetTimeString(int weak, char *pszTime)
{
    const char *arrpszTime[7] = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"};

    if (weak >= 1 && weak <= 7)
    {
        sprintf(pszTime, "%s", arrpszTime[weak - 1]);
    }
    else
    {
        sprintf(pszTime, "未知");
    }
}

学会了简单的表驱动编程后,但是在实际开发中还是不知道在什么情况下使用,那么什么情况下适合表驱动开发呢?

1、常见的有驱动开发,比如采用了多个相同的驱动芯片,但是引脚等不同,可能有些人调试完其中一个驱动后,会拷贝一份再修改引脚等,这样无疑是浪费了 Flash 空间,此时采用表驱动方式将引脚等作为数据,驱动作为逻辑,只采用一份驱动代码,可以无限扩展多个驱动芯片。

2、EEPROM 数据处理,通常包括地址、数据值、最大值、最小值和默认值等,他们的方式处理是一样的,可以将需要保存的数据做成一个数组表,通过相同的函数处理这些数据。

3、按键、菜单、LED等等模块都可以采用表驱动的方式处理,比如按键将引脚、按下电平、当前状态等作为数据,菜单将每个选项和函数指针等作为数据。

4、其他等等经过思考后能够转成数据的情况。

代码参考:

按键:https://gitee.com/const-zpc/FML_KEY.git(按键管理表,包含引脚、按下电平、当前状态等)

菜单:https://gitee.com/const-zpc/menu.git(菜单选项表,包含菜单选项名称、子菜单、函数指针【后续的动作】等)

OLED:https://gitee.com/const-zpc/STM32_OLED.git (字库数据表,包含字体索引、字体数据等)

ESP8266:https://gitee.com/const-zpc/esp8266.git (AT指令数据表,包含指令、期望响应、时间和函数指针【后续的动作】等)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK