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

执行默认情况

相关推荐
東隅已逝,桑榆非晚9 小时前
字符函数和字符串函数
c语言·笔记
AI科技星12 小时前
第二章 平行素数对网格:矩形→等腰梯形拓扑变换(完整公理终稿)
c语言·开发语言·线性代数·算法·量子计算·agi
社交怪人14 小时前
【歌手大奖赛】信息学奥赛一本通C语言解法(题号2072)
c语言·算法
Chen_harmony15 小时前
【习题02】打印菱形
c语言
handler0117 小时前
【Linux 网络】一文读懂 HTTP 协议
linux·c语言·网络·c++·笔记·网络协议·http
我还记得那天17 小时前
用C语言实现一个简易扫雷小游戏
c语言·开发语言
我不是懒洋洋18 小时前
【C++】类和对象( 类的定义、实例化、 this指针、 C++和C语言实现Stack对比)
c语言·开发语言·数据结构·c++·经验分享·算法·visual studio
『昊纸』℃18 小时前
《C语言程序设计(第3版)》课后答案.pdf
c语言·程序设计·vc++6.0·课后答案·实训题
guygg8818 小时前
贝叶斯非局部均值降噪算法C语言实现
c语言·算法·均值算法
WYH28718 小时前
C语言结构体变量和结构体指针详解:定义、访问、传参与易错点总结
c语言·开发语言·算法