【问题标题】:Cleanly access array of structures based on a value基于值干净地访问结构数组
【发布时间】:2014-11-25 08:58:59
【问题描述】:

我正在尝试创建一组结构,其中为每个加入网络的设备和运行程序的设备创建一个条目。应使用感兴趣设备的网络地址访问此数组。

示例:网络上有三个(其他)设备,地址分别为 0x1、0x2 和 0x3(我们在 0x0 上运行)。现在我们要访问与设备 0x1 相关的数据结构,假设是 Table[0]。问题是将地址(0x1)与索引(0)关联起来。

注意:网络地址由软件的其他部分动态分配,在我的控制之下。它们也保证是连续的。

最干净的方法是什么?

对我来说最直观的方法是搜索整个表比较每个条目的Address字段与特定地址(在示例中为0x1),然后返回索引,但我想知道是否有一种更合适的方式来执行此常见操作。顺便说一句,它可能有一个合适的名称(动态数据结构?)。

【问题讨论】:

    标签: c arrays data-structures embedded


    【解决方案1】:

    1) 快速、简单、肮脏的方法。如果地址是小数字,您可以简单地制作一个查找表,例如:

    const struct_ptr* TABLE[n] =
    {
      NULL,
      &struct_this,
      &struct_that,
      NULL,
      ...
    };
    

    索引对应于地址的位置。如果地址有对应的结构,则得到一个指向该结构的指针,否则为NULL。

    这是最快的方法,它可以直接访问O(1)。但它会浪费一些数据内存,如果您的地址可以是任何类型的数字,这实际上是不可行的。

    2) 排序查找表和二分查找。如果地址是任何类型的数字,请使用此选项。在这种情况下,您将不得不创建一个仅包含指向现有结构的指针的查找表,例如:

    const struct_ptr* TABLE [NUMBER_OF_EXISTING_STRUCTS] = 
    {
      &struct_this,
      &struct_that,
      ...
    };
    

    每个结构都需要有一个成员address,并且必须以排序的方式将它们添加到上述查找表中,最低地址在前。然后,您可以对表进行二分搜索,并使用比较函数比较每个结构 address 成员。这相当快,O(log n)

    3) 哈希表。 最先进的替代方案。这对于具有大量数据的系统最有效,并且还可以处理重复。访问时间几乎是确定性的,接近 O(log n),但不完全是。取决于您如何实现“链接”等。

    【讨论】:

    • 谢谢!请注意,地址分配在其他地方,无法控制。因此我不能指望它们是连续的,所以我想我必须实现 2 或 3。我已经用(重要的)添加编辑了这个问题。
    • @clabacchio 我想说 2) 最有可能并且它适用于嵌入式系统,因为它是 100% 确定性的。哈希表通常依赖于动态内存分配,在您的情况下可能是多余的。
    • 我得出了同样的结论,我不需要复杂的寻址,因为条目太少了。非常感谢您的详尽回答。
    • @clabacchio 如果您选择 (2),您可能希望从 qsortbsearch 标准库函数开始。您只需要实现比较功能,所以它是一个比较快的开始。
    • @user694733 qsort 不应该是必需的,因为结构和它们的地址在编译时是已知的。
    【解决方案2】:

    可能不是一个确定的答案,但我发现了一个提示,可能没有比手动搜索索引更好的解决方案。

    在 cprogramming.com 上,关于Hash tables

    像 C 这样的语言的最大缺点之一是没有键控数组。在普通的 C 数组(也称为索引数组)中,访问元素的唯一方法是通过其索引号。

    因此,我必须实际扫描数组以查找具有该地址的条目并从中获取索引。

    【讨论】:

    • 这并不是一个真正的语言弱点,因为如果你在语言中实现诸如 C++ std::map 之类的东西,然后使用让我们说字符串作为索引,编译器仍然必须将其实现为一些某种哈希表。因此,仅仅因为 C 中没有对它的语言支持,并不意味着用另一种语言编写的相同代码会比手动 C 解决方案更快。这里 C 和其他语言的唯一区别是 C 强制你自己编写代码。
    • (当然,为每个项目编写自己的哈希表远非理想,因为您可以将时间花在实际应用程序上。另外,最好让一些算法专家编写为您创建哈希表并对其进行测试,而不是破解您自己的东西,这可能存在错误和性能故障。)
    • @Lundin 好吧,我想我得把一些东西放在一起,它不会是一张大桌子(少于 10 个条目),我独自一人。
    猜你喜欢
    • 1970-01-01
    • 2014-01-10
    • 2014-06-14
    • 1970-01-01
    • 1970-01-01
    • 2018-06-20
    • 2013-03-01
    • 1970-01-01
    • 2014-09-15
    相关资源
    最近更新 更多