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个
- 一个函数的代码太长, 看不见头尾. 这样你难以把握整体意思.
- 函数封闭不了,一旦要添加一个消息,或者修改一个消息,又要改这个大函数.
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
执行默认情况