我声明了几个包含不同数据的struct
。我还有一个与这些结构相对应的enum
。我的代码中有几个地方需要访问有关结构的信息,我通过枚举来完成。这导致很少switch
个语句返回此信息。
我已将这些switch
语句包含在自己的函数中,以便尽可能重用。这导致三个功能看起来非常相似。
psuedo-code示例:
#include <stdio.h>
typedef struct
{
int varA;
char varB;
} A;
typedef struct
{
int varA;
int varB;
int varC;
} B;
typedef struct
{
int varA;
short varB;
} C;
typedef enum { structA, structB, structC } STRUCT_ENUM;
int returnSize(STRUCT_ENUM structType)
{
int retVal = 0;
switch(structType)
{
case structA:
retVal = sizeof(A);
break;
case structB:
retVal = sizeof(B);
break;
case structC:
retVal = sizeof(C);
break;
default:
break;
}
return retVal;
}
void printStructName(STRUCT_ENUM structType)
{
switch(structType)
{
case structA:
printf("Struct: A\r\n");
break;
case structB:
printf("Struct: B\r\n");
break;
case structC:
printf("Struct: C\r\n");
break;
default:
break;
}
}
void createDataString(STRUCT_ENUM structType, char* output, unsigned char* input)
{
switch(structType)
{
case structA:
{
A a = *(A*)input;
sprintf(output, "data: %d, %d", a.varA, a.varB);
break;
}
case structB:
{
B b = *(B*)input;
sprintf(output, "data: %d, %d, %d", b.varA, b.varB, b.varC);
break;
}
case structC:
{
C c = *(C*)input;
sprintf(output, "data: %d, %d", c.varA, c.varB);
break;
}
default:
break;
}
}
int main(void) {
char foobar[50];
printf("Return size: %d\r\n", returnSize(structA));
printStructName(structB);
C c = { 10, 20 };
createDataString(structC, foobar, (unsigned char*) &c);
printf("Data string: %s\r\n", foobar);
return 0;
}
这些自由函数基本上包含相同的switch
,并且在案例中放置了不同的代码。通过此设置,添加新的struct和enum值会导致代码中需要更改的三个位置。
问题是:有没有办法将其重构为更易于维护的东西?附加约束是代码是用C语言编写的。
编辑:在线示例:http://ideone.com/xhXmXu
答案 0 :(得分:3)
您始终可以使用静态数组并使用STRUCT_ENUM
作为索引。鉴于你的功能的性质,我不知道你是否会认为它更易于维护,但它是我通常喜欢的替代品,名称和尺寸的例子:
typedef enum { structA, structB, structC, STRUCT_ENUM_MAX } STRUCT_ENUM;
char *struct_name[STRUCT_ENUM_MAX] = {[structA] = "Struct A", [structB] = "Struct B", [structC] = "Struct C"};
size_t struct_size[STRUCT_ENUM_MAX] = {[structA] = sizeof(A), [structB] = sizeof(B), [structC] = sizeof(C)};
对于打印内容,你可以保留一个类似的函数数组,接收一个void *
来打印这个参数的值。
修改强> 根据Jen Gustedt的评论添加了指定的初始化程序。
答案 1 :(得分:1)
您可以使用附加参数将其转换为单个功能和单个开关。像这样
int enumInfo(STRUCT_ENUM structType, int type) // 1 = returnSize 2 = printStructName
{
int retVal = 0;
switch(structType)
{
case structA:
If ( type == 1 ) { retVal = sizeof(A); }
else { printf("Struct: A"); }
break;
case structB:
If ( type == 1 ) { retVal = sizeof(B); }
else { printf("Struct: B"); }
break;
case structC:
If ( type == 1 ) { retVal = sizeof(C); }
else { printf("Struct: C"); }
break;
default:
break;
}
return retVal;
}