c - 翻译结构项的有效方法,避免 C 中的 switch-case

标签 c algorithm switch-statement

我有以下情况:有一个结构,上面有很多不同类型的数据。还有另一个具有整数成员的结构,我将 ID 对应于我想要的第一个结构的数据。还有第三个结构应该携带该数据。例如:

struct MyData
{
    char data1;
    float data2;
    short data3;
    //...
};

struct MyRequest
{
    int desiredDataId;
};

struct DataValue
{
    long data;
};

在系统中,我通过 MyRequest 向它的一部分发送一条消息,告诉它“我想要数据 X”。然后系统应该查看请求的Id对应的对应缓冲区(MyData成员);然后创建一个 DataValue 并将所需的数据(转换)放入 data 成员。

要点:系统根据 MyRequest 的 Id 识别正在请求哪些 MyData 成员的部分最明显的方法是使用 switch-case:

switch(MyRequest.desiredDataId)
{
    case 0: //Id correspondent to data1
        DataValue.data = (long) MyData.data1;
        break;
    case 1: //Id correspondent to data2
        DataValue.data = (long) MyData.data2;
        break;
    case 3: //Id correspondent to data3
        DataValue.data = (long) MyData.data1;
        break;
    //...
}

问题:当 MyData 中的成员数量较少时,这很好;但我需要一个非常大的 MyData 的解决方案 - 目前,一个拥有大约 370 个成员的解决方案,这将导致一个巨大的 switch-case - 370 个案例!

问题:有没有其他方法可以使用更少的编码来进行这种映射?

目前,我的另一种选择是创建一个 void* 数组,它将指针映射到 MyData(在我的例子中是全局声明的)。因此,我必须首先设置一个巨大的数组,然后才调用

DataValue.data = *(long)pointerArray[MyRequest.data]

问题是,尽管避免了巨大的 switch-case,但现在我不得不面对巨大的数组初始化,所以不是“主解决方案”。

还有其他可行的选择吗?

注意:如果我写错了 C 语法,请原谅我;我急着写这个问题:)

最佳答案

您的问题似乎是使用像哈希表这样的键/值存储的经典情况(在 c 中有例如 ghashuthash ),其中 MyRequest.data(又名 MyRequest.desiredDataId)将是键和 DataValue.data 将是值。您使用 void 指针的解决方案几乎是最简单的实现:由于所有键都是整数,因此散列函数是身份函数。

我不确定您为什么要寻找替代方案,但如果它是速度并且您确实找到了比哈希表更快的东西,我相信全世界都想知道。我认为您的 void* 解决方案尽可能快(我希望您实际上并没有使用 char、int 和 float,但这些只是示例,而 long cast 是类似于序列化例程的抽象形式 -如果不是,则采用长数组,进行赋值,并保存间接寻址)。

但是,正如我猜想的那样,如果您不想在实现和维护数据结构时遇到麻烦,那么您应该能够使用哈希表获得相对快速的解决方案。

关于c - 翻译结构项的有效方法,避免 C 中的 switch-case,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25575412/

相关文章:

ruby - || 的多个 case/when 条件

PHP - switch case 中 break 和 continue 的区别

c - 选择 EBADF : which FD is bad?

c - 链表段错误

performance - Case 与 If Else If : Which is more efficient?

algorithm - 我怎么知道这些嵌套语句将执行多少次?

c++ - 使用快速排序对数组进行排序

c - 是什么阻止了将函数参数用作隐藏指针?

c - 从 FAT12 查找可用软盘空间

algorithm - WA on SCUBADIV spoj