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_arraytype 处,要刚好能拿到其对应的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_array0);

复制代码
// 使用函数指针数组
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/C++八股:(二十六)IIC 专题(I²C)---- 上集
c语言·c++·单片机
程序员Rock16 小时前
上位机开发-MODBUS面试常见问题
c语言·c++·面试·职场和发展·上位机
blevoice21 小时前
抖抖燃脂机单 AC6966B 主控调试踩坑:Type-C 整机供电喇叭无声排障
c语言·开发语言·单片机
小小晓.21 小时前
C++小白记:C风格字符串和数组用法
c语言·开发语言·c++
深念Y1 天前
开发者如何清理和迁移C盘堆积的垃圾
c语言·开发语言
十月的皮皮1 天前
STM32从零到量产开发:四路继电器工业控制模块开发实战笔记(小白视角)
c语言·笔记·stm32·stm32cubemx·hal库
不正经学生1 天前
C 语言函数深入剖析(基础篇)—— 从零理解函数的每一个细节
c语言·开发语言·数据结构·算法·c#
天空'之城1 天前
C 语言工业级通用组件手写 10:字节序转换
c语言·字节序·大小端·嵌入式通信·工业级组件
C++ 老炮儿的技术栈1 天前
OpenCV 实现社保卡透视矫正:Hough 直线提取四角并转正证件图像
c语言·c++·人工智能·opencv·算法·计算机视觉·c
我叫洋洋1 天前
C ++ [ hello world ]
c语言·c++·算法