【问题标题】:How do I implement a bit array in C / Objective C如何在 C / Objective C 中实现位数组
【发布时间】:2011-04-14 05:52:38
【问题描述】:

iOS / Objective-C:我有大量的布尔值。

这是一种存储这些值的低效方式——当只需要一个元素时,每个元素至少使用八位。

如何优化?

【问题讨论】:

  • 您是否尝试过搜索以查看是否有人写了您可以使用的东西?人们不会只为你编写代码。
  • 我实际上是想通过提问和回答来分享我写的一些代码,但是这个网站太快了!!!在我整理答案的 10 分钟内,已经出现了两个答案!
  • SO 并不是要发布您可以自己回答的问题。即便如此,您也可能会考虑在网络上查看该主题的现有内容,并将您的方法与您发现的内容进行比较。
  • 尊敬的,如果您阅读了常见问题解答的前几行,它会说“请在您提问之前查看您的问题是否已经被问过(甚至可能已经回答!)。只要您假装自己处于危险境地,问和回答自己的问题也很好:以问题的形式表达出来。我检查了这个主题尚未在 SO 上涵盖,并发布,因为我认为我的代码可以帮助人们。

标签: objective-c c ios core-foundation bitarray


【解决方案1】:

请参阅 CFMutableBitVector/CFBitVector 了解 CFType 选项

【讨论】:

  • 但是这些类存储 CFBit 对象,这些对象被类型化为 32 位整数。所以这个解决方案浪费了同样多的内存。
  • @whitman 值作为 CFBit 传递;这并不意味着它们被存储。我只是查看了 CFBitVector (r.550.13) 的实现。内存消耗为一位,而分配大小四舍五入为可被 64 整除的数字。总体而言,这是一个非常保守的实现。
【解决方案2】:

试试这个:

#define BITOP(a,b,op) \
 ((a)[(size_t)(b)/(8*sizeof *(a))] op ((size_t)1<<((size_t)(b)%(8*sizeof *(a)))))

那么对于任何不大于size_t 的无符号整数元素数组,BITOP 宏可以将数组作为位数组进行访问。例如:

unsigned char array[16] = {0};
BITOP(array, 40, |=); /* sets bit 40 */
BITOP(array, 41, ^=); /* toggles bit 41 */
if (BITOP(array, 42, &)) return 0; /* tests bit 42 */
BITOP(array, 43, &=~); /* clears bit 43 */

等等

【讨论】:

  • 如果您关心对任何 C 环境的完全可移植性,请将 8 替换为 CHAR_BIT
  • 实际上,如果您不介意在CHAR_BIT&gt;8 的平台上浪费位,8 在任何地方都可以正常工作,并且它会比引入诸如除以 9 或 10 之类的东西提供更好的性能...跨度>
  • 为了支持清空操作 &=~ 即两个运算符 &= 和 ~,您需要将宏的后半部分包装在另一组括号中。否则你会写一些你不想写的东西。 #define BITOP(a, b, op) ((a) [(size_t) (b) / (8 * sizeof *(a))] op ((size_t) 1 &lt;&lt; ((size_t) (b) % (8 * sizeof *(a)))))
  • @KevinConner:谢谢。我认为它现在已修复。
【解决方案3】:

您使用按位逻辑运算和位移。 (谷歌搜索这些术语可能会给你一些例子。)

基本上,您声明一个整数类型(包括intchar 等),然后将整数值“移位”到所需的位,然后对整数执行 OR 或 AND。

一些简单的说明性示例(用 C++ 编写):

inline bool bit_is_on(int bit_array, int bit_number)
{
   return ((bit_array) & (1 << bit_number)) ? true : false;
}

inline void set_bit(int &bit_array, int bit_number)
{
   bit_array |= (1 << bit_number);
}

inline void clear_bit(int &bit_array, int bit_number)
{
   bit_array &= ~(1 << bit_number);
}

请注意,这提供了恒定大小(sizeof(int) * 8 位)的“位数组”。也许这对您来说没问题,或者您可能想在此基础上构建一些东西。 (或者重新使用某些库提供的任何东西。)

这将使用比bool 数组更少的内存...但是...编译器生成的用于访问这些位的代码将更大且更慢。因此,除非您有大量需要包含这些位数组的对象,否则它可能会对速度和内存使用产生净负面影响。

【讨论】:

  • 该问题未标记为 C++。也许您应该将代码转换为 C。
  • @JeremyP - 无论如何,这是一个说明性的例子。我决定使用引用而不是指针,因为我认为这样可以减少对所提问题的注意力。我认为这点很好理解,无论如何,答案并不是要复制粘贴到某人的解决方案中。
  • 问题是关于 C 的。提问者甚至可能不知道什么是引用。如果是这样的话,你并没有少分心,而是分心了更多。
【解决方案4】:
#define BITOP(a,b,op) \
   ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))

不会工作...

修复:

#define BITOP(a,b,op) \
 ((a)[(size_t)(b)/(8*sizeof *(a))] op ((size_t)1<<((size_t)(b)%(8*sizeof *(a)))))

【讨论】:

    【解决方案5】:

    我在编写一个位数组框架时遇到了这个问题,该框架旨在管理类似于 Java BitSet 的大量“位”。我正在查看我决定的名称是否与其他 Objective-C 框架冲突。

    无论如何,我才刚刚开始,正在决定是否将其发布在 SourceForge 或其他开源托管网站上。

    如果你有兴趣,请告诉我

    编辑:我在 SourceForge 上创建了名为 BitArray 的项目。源代码在 SF SVN 存储库中,我还上传了一个已编译的框架。这个LINK 会让你到达那里。

    • 弗兰克

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-12
      • 2017-05-23
      • 2014-09-13
      • 1970-01-01
      相关资源
      最近更新 更多