ユニオンのすべてのメンバーが同じメモリを占有しているため、互いにオーバーレイされています。 1人の組合員に書き込むと、すべて組合のメンバーが更新されます。
unione
に2人のメンバーを保存するように設定しました。 lungo
はlong
であり、ch
はsizeof long
バイト(システムに応じて4または8バイト)を保持するサイズのchar
の配列です(この説明では4バイトと仮定します)。これらのメンバーは、互いに重なり合っています(同じ4バイトのメモリを占有します)。
ビッグエンディアンのシステム上でそれを覚えて、マルチバイトタイプの最も重要なバイトは、アドレスAに保存され、最下位バイトは、アドレスA + 3で保存されます。リトルエンディアンシステムでは、その順序が逆になります。最下位バイトがアドレスAに保存され、最上位バイトがアドレスA + 3で保存されます。
BE: A A+1 A+2 A+3 where A is arbitrary address
---- ---- ---- ----
lungo: 0x00 0x00 0x00 0x01
---- ---- ---- ----
LE: A+3 A+2 A+1 A
アレイ、一方で、常に、a[0]
は、アドレスAに格納されているように保存されています
したがって
BE: ch[0] ch[1] ch[2] ch[3]
----- ----- ----- -----
lungo: 0x00 0x00 0x00 0x01
----- ----- ----- -----
LE: ch[3] ch[2] ch[1] ch[0]
、リトルエンディアンのシステムで:我々は両方のビッグエンディアンとリトルエンディアンのシステム上lungo
に関連してch
を見れば、我々は以下を参照してくださいのでa[1]
は、などA + 1、に格納されています、ch[0]
は、lungo
の最下位バイトに対応し、 hは値0x01
を含んでいます。ビッグエンディアンシステムでは、lungo
の最上位バイトに対応するch[0]
は、値0x00
を含みます。
これはエンディアンを決定する一般的なトリックですが、厳密には動作は定義されていません。あなたは組合の一人のメンバーに書き込みをし、別のメンバーから読むはずがありません。このテクニックは "マルチバイトタイプ"がchar
またはunsigned char
の配列にきれいにマッピングされるために機能しますが、一般的に2つのマルチバイトタイプの間に完全に適用できるものではありません。
少なくとも私が知っている限り、システムのエンディアンを決めるのに100%のポータブルな、標準に準拠した方法はありません。私は
long l = 0x00010203;
char *c = (char *) &l;
if (c[0] == 0x03)
// little-endian
else if (c[0] == 0x00)
// big-endian
else
// something else
のように、このまたはタイプpunningのいくつかの種類のようなトリックを伴う知っているすべてのものはやはり、これは良い習慣ではなく、おそらく定義されていませんが、それはほとんどの場合、「働きます」。
大小エンディアンのみが可能な順序ではなく、1つのシステムで複数の順序が可能です。 VAXenは、普通はリトルエンディアンで、32ビットの浮動小数点数を除いて、「中間エンディアン」で2301にレイアウトされています。
まず第一に、コンパイラは大きくてもリトルエンディアンでもなく、アーキテクチャは.. UB、あなたはlungoを書いていますが、chを読んでいます。 –
@ SandBag_1996: 'char'とのユニオンによるエイリアスは合法です。 – Olaf
Cの本を使って 'ユニオン 'が何であるかを学んでください。それがあなたの大きな問題です。 – Olaf