switch-case 语句分析(消灭swich-case方法)


author: hjjdebug

date: 2026年 01月 23日 星期五 10:46:02 CST

descrip: switch-case 语句分析(消灭swich-case方法)


文章目录

  • [1. switch-case 的缺点](#1. switch-case 的缺点)
  • [2. 消灭switch-case 的两种方式.](#2. 消灭switch-case 的两种方式.)
    • [2.1. 刻意定义的函数指针数组](#2.1. 刻意定义的函数指针数组)
    • [2.2. 更一般的type-handler 结构体数组](#2.2. 更一般的type-handler 结构体数组)
  • [3 完整的演示代码(c代码):](#3 完整的演示代码(c代码):)
  • 4.程序运行结果:

1. switch-case 的缺点

switch-case语句不符合封闭性原则. 我见过一个家伙写MFC的消息分发函数,写了几千行.

显著的毛病有2个

  1. 一个函数的代码太长, 看不见头尾. 这样你难以把握整体意思.
  2. 函数封闭不了,一旦要添加一个消息,或者修改一个消息,又要改这个大函数.

2. 消灭switch-case 的两种方式.

2.1. 刻意定义的函数指针数组

把消息的处理部分定义成一个个函数, 把这些函数地址组织成一个数组.

即func_array[]={handler1,handler2,...}

就是说知道了type, 则从func_array[type] 处,要刚好能拿到其对应的handler.

这要求type从0开始,并且type还连续, 并且你还要把type对应的handler,正好放到

func_array 数组的对应位置处.

用法示例:

// 函数指针数组

void (*func_array[])(void) = {case_0, case_1, case_2};

int array_size = sizeof(func_array) / sizeof(func_array[0]);

复制代码
// 使用函数指针数组
if (type >= 0 && type < array_size) {
    func_array[type]();
} else {
    default_case();
}

2.2. 更一般的type-handler 结构体数组

没有那么多正好, type可能是随便定义的, 那应该用结构数组来代替函数数组.

让每一种type,都对应一个handler,构建成结构数组.

以后根据类型type, 就能找到对应的handler, 这是更一般的应对散转类型的方式

用法示例:

// 方法2: 定义结构体(适用于不连续值)

typedef struct {

int type;

void (*func)(void);

} switch_case_t;

复制代码
//定义查找表
switch_case_t switch_table[] = {
    {0, case_0},
    {5, case_1},
    {10, case_2}
};
int table_size = sizeof(switch_table) / sizeof(switch_table[0]);

// 根据type,查找对应的处理函数,并执行之
int found = 0;
for (int i = 0; i < table_size; i++) {
    if (switch_table[i].type == type) {
        switch_table[i].func();
        found = 1;
        break;
    }
}

if (!found) { //未找到,执行默认选项
    default_case();
}

为什么我们能够消灭switch-case, 是怎样消灭的switch-case. 我常常问自己.

因为我们把handler 组织了起来, 我们通过查找一个数组或者链表找到handler

而这个查找的过程用的是遍历,没有用switch-case, 找到了hander,则执行handler,

用此法消灭了swich-case.

3 完整的演示代码(c代码):

cpp 复制代码
$cat case.c
#include <stdio.h>

// 定义处理函数
void case_0() {
    printf("执行 case 0\n");
}

void case_1() {
    printf("执行 case 1\n");
}

void case_2() {
    printf("执行 case 2\n");
}

void default_case() {
    printf("执行默认情况\n");
}

int main() {
    int type = 1;
    
// 方法1: 使用函数指针数组(适用于连续值)
    // 精心构建一个函数指针数组,让func_array[type]就存储有对应的handler
    void (*func_array[])(void) = {case_0, case_1, case_2};
    int array_size = sizeof(func_array) / sizeof(func_array[0]);
    
    // 使用函数指针数组
    if (type >= 0 && type < array_size) {
        func_array[type]();
    } else {
        default_case();
    }
    
// 方法2: 定义结构体(更一般的情况)
    typedef struct {
        int type;
        void (*func)(void);
    } switch_case_t;
    //定义查找表 
    switch_case_t switch_table[] = {
        {0, case_0},
        {5, case_1},
        {10, case_2}
    };
    int table_size = sizeof(switch_table) / sizeof(switch_table[0]);
    
    // 查找匹配项
    int found = 0;
    for (int i = 0; i < table_size; i++) {
        if (switch_table[i].type == type) {
            switch_table[i].func();
            found = 1;
            break;
        }
    }
    
    if (!found) {
        default_case();
    }
    
    return 0;
}

4.程序运行结果:

$ ./case

执行 case 1

执行默认情况

相关推荐
LYS_06182 小时前
寒假学习(2)(C语言2+模数电2)
c语言·学习·算法
试剂小课堂 Pro3 小时前
mPEG-Silane:mPEG链单端接三乙氧基硅的亲水性硅烷偶联剂
java·c语言·网络·c++·python·tomcat
嵌入式小能手4 小时前
飞凌嵌入式ElfBoard-系统信息与资源之休眠
c语言·开发语言·算法
LYS_06184 小时前
寒假学习(5)(C语言5+模数电5)
c语言·学习·模数电
一个平凡而乐于分享的小比特5 小时前
ARRAY_SIZE宏作用及使用注意事项
c语言·array_size·内核宏
leaves falling5 小时前
c语言-编译和链接
c语言·开发语言
VekiSon5 小时前
ARM架构——UART 串口通信详解
c语言·arm开发·单片机·嵌入式硬件
LYS_06185 小时前
RM赛事C型板九轴IMU解算(3)(姿态融合算法)
c语言·算法·imu·姿态解算·四元数到欧拉角
杜子不疼.6 小时前
【Linux】基础IO(一):C 接口文件讲解
linux·c语言·开发语言·人工智能