私は2KBのSRAMしか持たないマイクロコントローラーに取り組んでおり、必然的にメモリを節約する必要があります。私は8を置くことができる方法を考え出そうとしています0
/1
値をビットフィールドを使用して1バイトに変換しますが、うまく処理できません。
struct Bits
{
int8_t b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1;
};
int main(){
Bits b;
b.b0 = 0;
b.b1 = 1;
cout << (int)b.b0; // outputs 0, correct
cout << (int)b.b1; // outputs -1, should be outputting 1
}
何ができますか?
すべてのビットフィールドメンバーは、符号付き1ビット整数です。 2の補数システムでは、これらはどちらか一方のみを表すことができることを意味します0
または-1
。使用する uint8_t
お望みならば 0
および1
:
struct Bits
{
uint8_t b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1;
};
注意として-この規格はビットフィールドの実装スキームを実際に強制するものではありません。 Bits
が1バイトになる保証はなく、仮想的にそれが大きくなることは完全に可能です。
しかし実際には、実際の実装は通常、明白なロジックに従い、「ほぼ常に」サイズが1バイトになりますが、これが保証されている必要はありません。念のため、念のため 手動で行う を使用してください。
ところで-1
はまだtrue
ですが、-1 != true
前述のように、これらの変数は符号ビットのみで構成されているため、使用可能な値は_0
_および_-1
_のみです。
これらのビットフィールドのより適切なタイプはbool
です。 C++ 14§9.6/ 4:
値
true
またはfalse
が任意のサイズ(1ビットのビットフィールドを含む)のbool
型のビットフィールドに格納されている場合、元のbool
値とビットフィールドの値は等しいと比較します。
はい、_std::uint8_t
_で十分ですが、最適な方法を使用することもできます。 std::cout << (int)b.b0;
のキャストのようなものは必要ありません。
符号付き整数と符号なし整数が答えです。
シグナリングは単なるビットの解釈であり、-1または1は「変数型」を解釈する「印刷」シリアライザにすぎないことに注意してください。コンパイラによって関数(演算子のオーバーロードを調べる)が「明らかにされた」ため、ビットは同じ、その値も(オン/オフ)-1ビットしかないため。
気にしないでくださいが、明示的にすることをお勧めします。符号なしで変数を宣言することをお勧めします。これにより、「print」のようなシリアライザに値を設定または取得するときに適切なコードをマウントするようコンパイラに指示します)。
"COUT"演算子のオーバーロード: "cout"は、パラメーターのオーバーロードが呼び出す関数をコンパイラーに指示する一連の関数を通じて機能します。したがって、2つの関数があり、1つは符号なしを受け取り、もう1つは符号付きを受け取るため、同じデータを異なる方法で解釈することができ、それを変更して、キャストを使用して別の関数を呼び出すようにコンパイラーに指示できます。 cout << myclass を参照