表驱动基础使用方法(C语言)

好久没有更新过文章了,今天加班正好没什么事,那就来聊聊驱动表的那些事(我也是小白,都是些很基础的东西哈哈)

什么是表驱动

我的理解是就像一种映射关系,比如你家的电话簿,一个人会对应一个电话号码、一个地址等等。
在这里插入图片描述
当我们要按照表中的几种情况做不同的操作时,就去查这个表,然后执行。怎么查呢?可以以某个元素作为判断依据,比如:以“名字“”作为判断依据

for  (int i = 0; i < 表长度; i++) {
	if (名字 == 李四) {
		电话 = xxx;
		地址 = xxx;
		// 其他操作

很easy对吧

一个简单实例

今天天气很好,你想去找黄老师吃他做的豆角了,但是你忘记了他的电话号码,也不知道他住在哪里的,还好你有一个10000人+的电话簿,里面每个人都记了电话和地址。

你的任务是从这个记录了10000个人以上的电话簿中找到黄老师的电话给他打过去,跟他说你今天要去找他。
输入:黄老师
输出:电话号码

现在我们构建一个结构体,里面的元素就是你电话簿记录的元素,以及定义出全局变量,作为电话簿

typedef enum {
    MR_LIU = 0,
    MR_HUANG,
    MR_HE,
    // 此处省略一万人
    PERSON_MAX_NUM,
} Name;

typedef struct {
    char phoneNumber[MAX_LENGTH];
} PhoneNum;

static struct PhoneBook {
    Name name;
    PhoneNum phoneNum;
} g_phoneBook[] = {
    { MR_HE, {"136xxx7556"} },
    { MR_HUANG, {"158xxx4366"} },
    { MR_LIU, {"137xxx9890"} },
    // 此处省略一万人
};

现在通过循环找一下黄老师的名字,得到电话号码

int main(int argc, const char *argv[])
{
    char phoneNumber[MAX_LENGTH] = {"0"};
    for (int i = 0; i < ARRAY_SIZE(g_phoneBook); i++) {
        if (g_phoneBook[i].name == MR_HUANG) {
            phoneNumber[0] = '\0'; // 清空字符串
            strcpy(phoneNumber, g_phoneBook[i].phoneNum.phoneNumber);
        }
    }
    printf("Found Mr. Huang's phone number: %s\n", phoneNumber);
    return 0;
}

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

进阶实例

你说这也太简单了,何况不用表驱动也能完成吧,直接拿个数组存一下,循环查找不就好了?体现不出表驱动的价值啊。
那现在上正菜:

输入:名字。
输出:如果是黄老师,则打印他的电话号码,并且告诉他买点豆角;如果是何老师,则打印他的地址,并告诉他晚上一起去黄老师家吃豆角;如果是宋老师,告诉她买点胃药。

同样,还是先构造结构体

typedef enum {
    MR_HE = 0,
    MR_HUANG,
    MRS_SONG,
    // 此处省略一万人
    PERSON_MAX_NUM,
} Name;

typedef struct {
    char phoneNumber[MAX_LENGTH];
} PhoneNum;

typedef struct {
    char address[MAX_LENGTH];
} Address;

然后用个全局变量构造一个表(其实就是结构体数组),表中最后一个元素就是该人所对应要执行的操作(函数)

static struct PhoneBook {
    Name name;
    PhoneNum phoneNum;
    Address addr;
    void (*doActions)();
} g_phoneBook[] = {
    { MR_HE, {"136xxx7556"}, {"Street1"}, CallMrHe },
    { MR_HUANG, {"158xxx4366"}, {"Street2"}, CallMrHuang },
    { MRS_SONG, {"137xxx9890"}, {"Street3"}, CallMrsSong },
    // 此处省略一万人
};
  • 其实这个表可以再优化一下,表已经按照枚举Name的顺序排好了,表的元素已经可以不加人名了。
static struct PhoneBook {
    PhoneNum phoneNum;
    Address addr;
    void (*doActions)();
} g_phoneBook[] = {
    { {"136xxx7556"}, {"Street1"}, CallMrHe },
    { {"158xxx4366"}, {"Street2"}, CallMrHuang },
    { {"137xxx9890"}, {"Street3"}, CallMrsSong },
    // 此处省略一万人
};

然后我们把对应函数补上

void CallMrHuang()
{
    printf("Found Mr. Huang's phone number: %s\n", g_phoneBook[MR_HUANG].phoneNum.phoneNumber);
    printf("Please buy some green beans\n");
}

void CallMrHe()
{
    printf("Address: %s\n", g_phoneBook[MR_HE].addr.address);
    printf("Let's go to Mr. Huang's house and eat green beans");
}

void CallMrsSong()
{
    printf("Please remember to buy some stomach medicine");
}

最后包装好最终函数,然后运行一下试试

void MakeSomeCall(Name name)
{
    g_phoneBook[name].doActions();
}
int main(int argc, const char *argv[])
{
    Name name = MR_HUANG;
    MakeSomeCall(name);
    return 0;
}

运行结果
如果输入是黄老师:
在这里插入图片描述
如果输入是何老师:
在这里插入图片描述
如何输入是宋老师:
在这里插入图片描述

总结

最后总结一下,为什么要用表驱动,如果用if语句不是也可以吗?
回答:如果情况很少,2、3个的话可以用if语句判断执行,如果情况有几十个呢?if语句过多,如果内层函数还包含循环嵌套那些,整个项目的圈复杂度将会非常高,影响运行的速率,代码整体质量下降。从上面的例子可以看到,我们甚至不需要去if判断,直接就能找到输入所对应的操作,效率非常的高,并且代码比较简洁易理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奇迹行者还在打野

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值