c语言 switch case 太多优化/重构[二]

1. 背景 - 某该函数switch case 复杂度太高 ,函数太长 pclint不过

CHAR * AB_FUN_XXXX(IN ULONG ulResult)
{
	UINT uiRcID;
	switch (ulResult)
	{
		case ERROR_SUCCESS:
			return NULL;
		case ERROR_NO_ENOUGH_RESOURCE:
			uiRcID = XX_YY_MEM_ALERT;
			break;
		case ERROR_BB_URL_GETFAILED:
			uiRcID = XX_YY_GETFAILED;
			break;
		case ERROR_BB_UPDATE_FAILED:
			uiRcID = XX_YY_FAILED;
			break;
		……
		default:
			uiRcID = XX_YY_GENERAL_FAILED;
			break;
	}
	
	return RUN_Test(uiRcID);
}

2. 解决 - 建表,查表处理

/* for AB_FUN_XXXX */
typedef struct tagErrorCodeToIDS
{
	UINT uiErrorCode;
	UINT uiIDS;
}ERROR_TO_IDS_S;

static ERROR_TO_IDS_S g_astErrorToIds[]=
{
	{ERROR_SUCCESS, 0},
	{ERROR_NO_ENOUGH_RESOURCE, XX_YY_MEM_ALERT},
	{ERROR_BB_URL_GETFAILED, XX_YY_URL_GETFAILED},
	{ERROR_BB_UPDATE_FAILED, XX_YY_FAILED},
	{ERROR_AB_PROC_UPDATE, XX_YY_PROC_UPDATE},
	{ERROR_AB_CANNOT_CONNECT, XX_YY_CANNOT_CONNECT},
	{ERROR_AB_CANNOT_CONNECT, XX_YY_CANNOT_CONNECT},
	{ERROR_AB_CONNECT_TIMEOUT, XX_YY_CONNECT_TIMEOUT},
	{ERROR_AB_MEM_ALERT, XX_YY_MEM_ALERT},
	……
}

CHAR * AB_FUN_XXXX(IN ULONG ulResult)
{
	UINT uiRcID = 0;
	ULONG ulLoop = 0;
	ULONG ulArrLen = 0;

	ulArrLen = sizeof(g_astErrorToIds)/sizeof(g_astErrorToIds[0]);

	for(ulLoop = 0; ulLoop < ulArrLen; ulLoop++)
	{
		if(ulResult == g_astErrorToIds[ulLoop].uiErrorCode)
		{
			uiRcID = g_astErrorToIds[ulLoop].uiIpsIDS;
		}
		……
	}
	……
}

3. witch case 原理/代码优化 重构

对于一个switch有几十个case的情况,其圈复杂度往往上百,程序块重构显然已不能解决其本质复杂度。
如果要降低其圈复杂度,必然需要对代码进行重新设计。

C语言的switch/case语言特性本质是描述一种查表逻辑,其中表结构和表的控制(即查表)都通过软件来表达。
表通过代码来描述,这显然不是一种最佳的实现方式。
我们需要做的就是,避免控制中的复杂性,将精力集中在数据的组织上,以反映所模拟世界的真实结构,并将数据与控制进行分离。

参考:

https://www.bbsmax.com/A/kvJ3L6bp5g/

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
C语言中,`switch` 语句用于根据某个表达式的值执行不同的代码块。当你遇到多个`case` 块具有相同的条件时,可以使用`default` 或者共享代码块的方式处理这种情况。 1. **使用`break`**:通常情况下,每个`case` 后面都跟着`break`语句,用来退出当前的`switch` 语句。如果你发现多个`case` 的条件都匹配,但它们后面的代码是相同的,可以在最后一个匹配的`case` 后不加`break`。程序会按顺序执行到下一个`break`为止。这样做的前提是后续的`case` 没有被匹配。 ```c switch (expression) { case value1: // 共享代码 // ... break; // 如果这是最后一个匹配的,可以省略break case value2: // 共享代码 break; // 更多case... default: // 其他情况 break; } ``` 2. **使用`fallthrough`(C99以后)**:在C99及以上版本,引入了`fallthrough`关键字,允许程序从一个`case` 直接跳转到下一个`case`,即使没有`break`。这可以避免重复代码,但要注意控制好代码流程,因为这不是标准行为,可能会导致意外的结果。 ```c switch (expression) { case value1: // 共享代码 fallthrough; // 使用fallthrough关键字 case value2: // 共享代码 break; // 更多case... default: // 其他情况 break; } ``` 3. **共享代码块**:另一种方法是在`switch` 之外定义一个代码块,然后在所有匹配的`case` 下调用这个代码块。这需要对代码进行一些重构,确保每个`case` 的逻辑可以正确地调用这个共享部分。 ```c void shared_code() { // 共享代码 } switch (expression) { case value1: case value2: shared_code(); // 其他case...中的代码 break; // 更多case... default: shared_code(); // 其他情况 break; } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值