【问题标题】:How to use an int as an array of ints/bools?如何将 int 用作整数/布尔数组?
【发布时间】:2010-02-26 01:56:08
【问题描述】:

我在编写程序时注意到我的许多int 类型变量从未超过十。我认为因为int 最短为 2 个字节(如果算上char,则为 1),所以我应该能够在一个短整数中存储 4 个unsigned ints,最大值为 15,我知道我可以使用>><< 单独访问每一个:

short unsigned int SLWD = 11434;
S is (SLWD >> 12), L is ((SLWD << 4) >> 12),
W is ((SLWD << 8) >> 12), and D is ((SLWD << 8) >> 12)

但是,我不知道如何将它包含在类函数中,因为任何类型的 GetVal() 函数都必须是 int 类型,这首先违背了隔离位的目的。

【问题讨论】:

  • 您存储了多少个这些小整数?你确定你会看到以这种方式包装它们的好处吗?你知道他们怎么说过早优化。如果您这样做是为了好玩,可以,但我敢打赌,您不会看到可衡量的性能提升。
  • 用您要询问的语言标记您的问题总是好的...
  • 我同意@Michael Petrotta 的观点。在许多情况下,增加额外的 OR 和位移指令的代码更改会增加内存使用量,而不是减少一些位所节省的内存。

标签: c++ memory-management bitwise-operators integer


【解决方案1】:

首先,记住Rules of Optimization。但这在 C 或 C++ 中使用位域是可能的:

struct mystruct {
    unsigned int smallint1 : 3; /* 3 bits wide, values  0 -- 7 */
    signed int   smallint2 : 4; /* 4 bits wide, values -8 -- 7 */
    unsigned int boolean   : 1; /* 1 bit  wide, values  0 -- 1 */
};

值得注意的是,虽然您不需要太多存储空间而获得收益,但您会因为访问所有内容变得更加昂贵而失败,因为现在每次读取或写入都有一堆与之相关的位旋转机制。鉴于存储很便宜,它可能不值得。

编辑:您也可以使用vector&lt;bool&gt; 来存储 1 位布尔值;但要小心它,因为它不像普通的vector!特别是,它不提供迭代器。完全不同的是,可以公平地说 vector&lt;bool&gt; 实际上不是 vector。 Scott Meyers 在 'Effective STL' 中写得很清楚。

【讨论】:

  • 我想它真正有用的唯一时间是如果我确实同时使用了数百个值。但很高兴知道我可以制作一个实际上只有 1 位的布尔值。 ^^
  • 谈到 1 位布尔值让我想起了向量,请参阅编辑后的答案。
  • 数百个值仍然只会为您节省数百或数千个字节......您需要谈论数万或数十万个实例才能开始变得很重要。 (当然在很多情况下你确实有这么多实例......)
  • sizeof(mystruct) 在我的编译器上是 4。小心结构填充。
  • @Justicle:+1 好点。填充会杀死所有的储蓄。答案是将更多值打包到结构中,使其为 32 位或 64 位宽(取决于实现)。
【解决方案2】:

在 C 中,仅出于节省空间的目的,您可以使用 bitfields 将 unsigned short 重新解释为结构(或使用此类结构而不会弄乱重新解释):

#include <stdio.h>

typedef struct bf_
{
   unsigned  x : 4;
   unsigned  y : 4;
   unsigned  z : 4;
   unsigned  w : 4;
} bf;


int main(void)
{
   unsigned short i = 5;
   bf *bitfields = (bf *) &i;

   bitfields->w = 12;
   printf("%d\n", bitfields->x);
   // etc..

   return 0;
}

【讨论】:

  • sizeof(bf) 在我的编译器上是 4。小心结构填充。
  • +1,和克里斯一样。这可能非常强大。要是有最喜欢的答案就好了……
  • Justicle:你是对的。最好选择与单词大小相同的结构(在我们的例子中是 32 位)。
【解决方案3】:

这是一种非常常见的技术。你通常分配一个更大的原始类型(例如,ints 或 longs)的数组,并有一些抽象来处理映射。如果您使用的是 OO 语言,通常最好实际定义某种 BitArray 或 SmartArray 或类似的东西,并实现一个获取索引的 getVal()。重要的是要确保隐藏内部表示的细节(例如,当你在平台之间移动时)。

话虽如此,大多数主流语言已经具备此功能。
如果您只想要位,WikiPedia 有一个很好的列表。 如果您想要的不仅仅是位,您仍然可以找到一些东西,或者使用类似的接口自己实现它。看看Java BitSet 供参考

【讨论】:

  • “重要的是确保隐藏内部表示的细节(例如,当你在平台之间移动时)。”便携性可能不重要,访问速度可能更重要。
猜你喜欢
  • 2013-07-04
  • 1970-01-01
  • 1970-01-01
  • 2011-08-20
  • 2011-03-11
  • 1970-01-01
  • 2023-03-11
  • 2016-11-21
  • 1970-01-01
相关资源
最近更新 更多