1

私は次の型の定義を持っています:

typedef union{
unsigned int Entry;
struct {
    unsigned char EntryType;
    unsigned char EntryOffset[3];
};
} TLineDescriptor;

私はまた、このタイプを次のように使用しています。

TLineDescriptor LineDescriptor;
LineDescriptor.Entry = 40;
LineDescriptor.EntryType = 0x81;

sizeof(LineDescriptor)は、この変数が4バイトのメモリを占有していることを示しています。これは、最初はintまたはstructのいずれかを保持していると想定していました。

cout << LineDescriptor.Entry << " " << LineDescriptor.EntryType << endl;

ただし、上の行は2つの異なる値を出力します。つまり129 üLineDescriptor.Entry値0x81が保存されたメモリ位置を参照しているようです。40で何が起こったのかわかりません。しかし、私の仮定が間違っていたことは明らかです。誰かが型の定義を正しく解釈して説明できますか?見つけたコードを操作することは私にとって非常に重要です。

前もって感謝します。

4

4 に答える 4

1

EntryTypeを次のように出力します。

cout << "0x" << hex << (unsigned)LineDescriptor.EntryType << endl;

üが0x81であることがわかります。

これを印刷する:

cout << LineDescriptor.Entry

は未定義の動作であり、ユニオン内の1つの要素のみが一度に「アクティブ」になる可能性があるためです。最後の割り当てはEntryTypeでした。

ただし、これが実際にはC ++が望むほど未定義ではないと想定できる場合、129は次のようになります。

Entry=40-これはシステム上でバイナリ形式です28 00 00 00(重要度の低いバイトが最初)。

LineDescriptor.EntryType = 0x81;最初のバイトを変更すると:-81 00 00 00エントリのプリントアウトは129になります。

この実験を行うと、他の結果が得られます。

TLineDescriptor LineDescriptor;

LineDescriptor.Entry = 256;
LineDescriptor.EntryType = 0x81;

cout << LineDescriptor.Entry << " " << unsigned(LineDescriptor.EntryType) 
     << endl;
>> 385  129
于 2012-10-28T23:54:18.113 に答える
1

実際、これらは異なる値ではありません。129文字の文字コードですü。扱いとデータ型operator <<が異なり、前者の数値と後者の文字値を出力します。ostreamintchar

したがって、共用体のタイプについてのあなたの理解は正しいです。ただし、共用体型を扱う場合はエンディアンが問題になる可能性があることに注意してください。たとえば、リトルエンディアンのマシンEntryTypeでは、の最下位バイトEntryEntryOffset配列が他のバイトを保持します。ただし、ビッグエンディアンマシンでEntryTypeは、最上位バイトを保持します。

于 2012-10-28T23:54:27.543 に答える
1

あなたの仮定は間違っていません、組合はintかstructのどちらかを保持します。0x81EntryTypeフィールドに値を割り当てると、以前に割り当てた整数Entryが上書きされます。そのため、cout両方のフィールドに同じ量が表示され、1つはint(129)として、もう1つはchar( ü)。どちらも16進値0x81です。

于 2012-10-28T23:57:59.450 に答える
1

intstruct同時に保持し、両方が同じメモリスペースを占有します。にアクセスすることによりTLineDescriptor::Entry、これらの4バイトを。として解釈しますint。を介してアクセスする場合はstruct、4秒と解釈しますunsigned char

LineDescriptor.Entry = 40;

これにより、4バイトがint値40に設定されます。スモールエンディアンシステムでは、これは最初のバイトが40で、他の3バイトが0であることを意味します。

LineDescriptor.EntryType = 0x81;

これにより、最初のバイトが値129(0x81)に設定されます。(スモールエンディアンシステムでは、これはEntry、残りが0に設定されている場合、の値も129になることを意味します)。

異なる出力について:EntryTypeを出力すると、数値ではなく文字として表示されます。試す:

cout << LineDescriptor.Entry << " " << static_cast<int>(LineDescriptor.EntryType) << endl;
于 2012-10-28T23:59:03.967 に答える