1. 構造体と共用体の違い
Struct のすべてのメンバーにはコンパイラによってメモリ領域が与えられるため、複数の変数を格納できます。
Union のメンバー変数はメモリ空間を共有し、最後の変数データのみを格納します。
まずはコードを見てみましょう
ユニオン部分:
ユニオン u { int a; int b; int c; };
main関数での代入
ca = 1;
cb = 2;
cc = 3;
cout << ca;
導き出された結論は、すべてのメンバー変数データが最後に割り当てられたデータであるということです。union を使用する場合は、値が必要な場合にのみ、union のメンバー割り当てによって残りのメンバーが書き換えられることをお勧めします。
構造部
struct l { 文字a; 文字b; int c; ダブルd; };
オブジェクトのデータは独立して保存されます
メモリサイズ(バイトアライメント)
連合
メモリの側面はさらに興味深いものです。前述の共用体は最後のビットのみを格納しますが、データ型が異なるため、共用体のサイズは最大ビットを使用します。
ユニオン u { 文字 a; int b; ダブルc; };
メイン関数で
cout << sizeof(c);
推測された
最大ビットはdouble型の8バイト
ユニオン u2
{ char a[13]; int b; };
ユニオン u3
{ char a[13]; 文字b; };
その場合、この 2 つの違いは、b の型が int と char であることです。
cout<<sizeof(u2)<<endl; // 16
cout<<sizeof(u3)<<endl; // 13
その結果、通常の計算では最大の文字 a[13] になるはずですが、結果は異なります
中心的な問題は、int 型が 4 バイトであるため、メモリ アライメントは 4 に基づく必要があるのに対し、char は 1 バイトであることです。
構造体のメモリ
構造体部分はさらに複雑で、上で述べたように、メモリのサイズを見るときはメモリのアライメントの問題を思い出す必要がありますが、具体的な計算は、最初にすべてを合計するのではなく、順番にアライメントできる最小の数に従ってアライメントを決定することです。
例:
struct k { char a; ダブルb; 文字c; int d; }; struct k2 { char a; 文字b; int c; ダブルd; };
int main()
{ か; k2b;
cout << " A:" << sizeof(a) << "B:" << sizeof(b);
}
k は 24、k2 は 16。2 つのサイズの違いの問題は、順序が異なることです。k1 が最初に検索され、見つかった最大のものは double クラスです。次に 8 ビットに整列し、a を 0 として計算し始め、次に 1 に達します。b を追加したい場合は 7 を超えるため、8 にジャンプして計算を開始し、アドレスを 15 に設定し、c を 16 に保存し、d を保存し続けます。結果は 20 です。データを 23 に整列すると、構造体のサイズは 23 になります (0 から開始することを忘れないでください)。
k2は16、aは0から1、bは1から2、cがint型の場合は4ビットでアライメントされます。cが超えてしまうので4から7からアライメントが始まり、格納されるdは8ビットですが4バイトでアライメントできるので、15に達するとk2のサイズは16になります。
構造体のメモリサイズは型と順序に関係します
要約する
最初に Union と struct について話しましょう。両方とも、前者は最後の値のみを保存し、そのサイズはバイト アラインメントと最大のデータ型によって決まります。後者の strcut はすべての変数にスペースを提供し、メモリのサイズは格納された型の順序にも関係します。これはより重要です。
データ型のサイズを貼り付けます。32 桁または 64 桁は、ポインターと Long の場合のみ異なります(データはここから取得されます)。
注:
1. Long は、Linux では 8 バイト、Windows では 4 バイトです。
2. 文字列のサイズ: 32 ビット文字列と 64 ビット文字列には 4 バイトの違いがあり、これは実際にはポインタの違いです。文字列は文字列自体を保存しませんが、文字列の先頭へのポインターを保存します。