19

ビットを配列(構造体など)に格納したい。だから私は次の2つのアプローチのいずれかに従うことができます

アプローチ番号1(AN 1)

struct BIT
{
   int data : 1
};

int main()
{
   BIT a[100];
   return 0;
}

アプローチ番号2(AN 2)

int main()
{
    std::bitset<100> BITS;
    return 0;
}

なぜ誰かがAN1よりもAN2を好むのでしょうか?

4

5 に答える 5

20

アプローチ番号のため。2は、実際には100ビットのストレージに加えて、非常に小さな(一定の)オーバーヘッドを使用しますが、nrは使用します。1は通常、Bit構造ごとに4バイトのストレージを使用します。一般に、astructはC++標準ごとに少なくとも1バイト大きいです。

#include <bitset>
#include <iostream>

struct Bit { int data : 1; };

int main()
{
    Bit a[100];
    std::bitset<100> b;
    std::cout << sizeof(a) << "\n";
    std::cout << sizeof(b) << "\n";
}

プリント

400
16

これとは別に、bitsetビット配列を多くの便利な操作を備えた優れたオブジェクト表現でラップします。

于 2010-10-22T15:03:53.567 に答える
7

良い選択は、ビットをどのように使用するかによって異なります。

std::bitset<N>固定サイズです。Visual C++10.0は非準拠のwrtです。コンストラクターへ。一般に、回避策を提供する必要があります。int皮肉なことに、これはMicrosoftがバグ修正だと考えていたためでした。私が覚えているように、彼らは引数を取るコンストラクターを導入しました。

std::vector<bool>とほぼ同じ方法で最適化されstd::bitsetます。コスト:インデックス作成は直接参照を提供しません(C ++には個々のビットへの参照はありません)が、代わりにプロキシオブジェクトを返します。これは、参照として使用するまで気付かないものです。利点:最小限のストレージで、必要に応じてベクトルのサイズを変更できます。

unsigned少数のビットを処理する場合は、egを使用することもオプションです(正式な保証は16ビットですが、実際には32以下です)。

最後に、すべての大文字の識別子は、名前の衝突の可能性を減らすために、慣例により(Microsoftを除く)マクロ用に予約されています。したがって、マクロ以外にはすべて大文字の識別子を使用しないことをお勧めします。また、マクロには常にすべて大文字の識別子を使用します(これにより、マクロの認識も容易になります)。

乾杯&hth。、

于 2010-10-22T15:29:28.460 に答える
2

ビットセットにはより多くの操作があります

于 2010-10-22T15:03:28.053 に答える
0

アプローチ番号1は、ほとんどの場合4バイト整数の配列としてコンパイルされ、それぞれの1ビットがデータの格納に使用されます。理論的には、スマートコンパイラでこれを最適化できますが、私はそれを当てにしません。

使いたくない理由はありますstd::bitsetか?

于 2010-10-22T15:03:15.707 に答える
0

ビットセットに関するcplusplus.comのページを引用すると、「クラスは通常の配列に非常に似ていますが、スペース割り当てを最適化しています」。intが4バイトの場合、ビットセットは32分の1のスペースを使用します。

sbibool bits[100]が示唆しているように、ほとんどの実装には1バイト以上のブールがあるため、実行してもビットセットよりも劣ります。

知的好奇心のみの理由で、独自のビットセットを実装したい場合は、ビットマスクを使用して実装できます。

typedef struct {
  unsigned char bytes[100];
} MyBitset;

bool getBit(MyBitset *bitset, int index)
{
  int whichByte = index / 8; 
  return bitset->bytes[whichByte] && (1 << (index = % 8));
}

bool setBit(MyBitset *bitset, int index, bool newVal)
{
  int whichByte = index / 8;

  if (newVal)
  {
    bitset->bytes[whichByte] |= (1 << (index = % 8));
  }
  else
  {
    bitset->bytes[whichByte] &= ~(1 << (index = % 8));
  }
}

(ちなみに、クラスの代わりに構造体を使用して申し訳ありません。私は学校の低レベルの割り当ての真っ最中なので、ストレートCで考えています。明らかに、クラスを使用することの2つの大きな利点は、演算子のオーバーロードと可変サイズの配列を持つ機能。)

于 2010-10-22T15:06:11.893 に答える