データ構造型(メモリの章)超完全構造、共用体、列挙型メモリ解釈(C言語エントリに適用可能)
1.構造の記憶
メモリアライメント
ルール:
1.構造体の最初のデータメンバーが格納されているアドレスは、構造体変数のオフセットが0であるアドレスです。
2.他の開始アドレスは、このタイプの変数が占有するメモリの整数倍です。これは、占有されているメモリの整数倍のデータで不十分な部分が埋められている場合です。
3.構造体が占める合計メモリは、構造体のメンバーの基本データ型の最大バイト数の整数倍です。
(図1-1を参照)
#include<stdio.h>
struct str1 {
// ??
char a; // 1 byte //此处若删除char a 则所占内存为 24 以验证规则 1;(自行验证)
int b; // 4 byte
float c; // 4 byte
double d; // 8 byte(最大)
char ch; // 1 byte
}s1; // 32 byte
//将结构体内部变量调换位置后结构体内存占用发生改变
struct str2 {
// ??
char a; // 1 byte
char ch; // 1 byte
int b; // 4 byte
float c; // 4 byte
double d; // 8 byte(最大)
}s2; // 24 byte
int main() {
printf("%d\n",sizeof(s1)); //输出结果:32
printf("%d\n",sizeof(s2)); //输出结果:24
return 0;
}
グラフィック1-1
構造に配列が含まれている場合:(図1-2を参照)
#include<stdio.h>
// 当结构体成员包含数组:
struct str3 {
int a; // 4 byte
double b; // 8 byte(最大)
char arr[9]; // 9 byte(char基本数据类型占 1byte)
}s3; // 结果:32
struct str4 {
double b; // 8 byte(最大)
int a; // 4 byte
char arr[9]; // 9 byte(char基本数据类型占 1byte)
}s4; // 结果:24
int main() {
//如果结构体成员含有数组:
printf("%d\n", sizeof(s3)); //输出结果:32
printf("%d\n", sizeof(s4)); //输出结果:24
return 0;
}
図1-2
構造に構造が含まれている場合:
#include<stdio.h>
struct str5 {
char ch;
short sh;
int num;
}s5;
struct str6 {
int n;
struct str5 s5;
}s6;
struct str7 {
int n;
char ch;
short sh;
int num;
}s7;
int main() {
//如果结构体成员包含结构体:
printf("%d\n", sizeof(s5)); //输出结果:8
printf("%d\n", sizeof(s6)); //输出结果:12 --> sizeof(int)+8
printf("%d\n", sizeof(s7)); //输出结果:12
return 0;
}
結論:構造体str6とstr7は同等であり、構造体のメンバーに構造体が含まれている場合、メンバー構造体のコンテンツを拡張することと同等です。
注:構造体メンバーに含まれる構造体は、それ自体にすることはできません。
[完全なコードは次のとおりです]
#include<stdio.h>
struct str1 {
// 内部求和为 18byte
char a; // 1 byte
int b; // 4 byte
float c; // 4 byte
double d; // 8 byte(最大)
char ch; // 1 byte
}s1; // 结果:32 byte
// 将结构体成员变量调换位置后结构体内存占用发生改变:
struct str2 {
// 内部求和为 18byte
char a; // 1 byte
char ch; // 1 byte
int b; // 4 byte
float c; // 4 byte
double d; // 8 byte(最大)
}s2; // 结果:24 byte
// 当结构体成员包含数组:
struct str3 {
int a; // 4 byte
double b; // 8 byte(最大)
char arr[9]; // 9 byte(char基本数据类型占 1byte)
}s3; // 结果:32
struct str4 {
double b; // 8 byte(最大)
int a; // 4 byte
char arr[9]; // 9 byte(char基本数据类型占 1byte)
}s4; // 结果:24
// 当结构体成员包含结构体:
struct str5 {
char ch;
short sh;
int num;
}s5;
struct str6 {
int n;
struct str5 s5;
}s6;
struct str7 {
int n;
char ch;
short sh;
int num;
}s7;
int main() {
printf("%d\n",sizeof(s1)); //输出结果:32
printf("%d\n",sizeof(s2)); //输出结果:24
printf("\n");
//如果结构体成员含有数组:
printf("%d\n", sizeof(s3)); //输出结果:32
printf("%d\n", sizeof(s4)); //输出结果:24
printf("\n");
//如果结构体成员包含结构体:
printf("%d\n", sizeof(s5)); //输出结果:8
printf("%d\n", sizeof(s6)); //输出结果:12
printf("%d\n", sizeof(s7)); //输出结果:12
return 0;
}
2.コンソーシアムの記憶
ルール:
1.サイズは、最も幅の広いメンバーを収容するのに十分な大きさである必要があります
。2。サイズは、含まれるすべての基本データ型のサイズで割り切れる可能性があります。
#include<stdio.h>
union MyUnion1{
char s[9]; // 9 byte (char类型为 1 byte)
int n; // 4 byte
double d; // 8 byte
}; // 16 byte
union MyUnion2 {
char s[5]; // 5 byte
int n; // 4 byte
double d; // 8 byte
}; // 8 byte
int main() {
printf("%d\n", sizeof(MyUnion1)); // 结果:16
printf("%d\n", sizeof(MyUnion2)); // 结果:8
}
3.列挙されたメモリ
#include<stdio.h>
enum Enum {
Enum1, // (int) 4 byte
Enum2, // (int) 4 byte
Enum3 // (int) 4 byte
}MyEnum;
int main() {
printf("%d\n", sizeof(MyEnum)); // 结果:4
printf("%d\n", sizeof(Enum1)); // 结果:4
printf("%d\n", sizeof(Enum2)); // 结果:4
printf("%d\n", sizeof(Enum3)); // 结果:4
return 0;
}
列挙に関する説明のほとんどは次のとおりです。列挙は4バイトです;(例:上記の状況)
-メモリを列挙する問題はそれほど深くする必要はありませんが、私はそれを探求したいと思います。
標準のC言語の説明では、列挙型が占めるスペースのサイズが明確に指定されていません。つまり、「列挙型のサイズは、最大の列挙型サブ値に対応できる整数のサイズです。」また、標準では次のように述べられています。「列挙型では、サブ列挙の値はint式を使用できる必要があります。」
#include<stdio.h>
enum Enum {
Enum1 = 0x7f7f7f7f7f, // (int类型最大值) (int) 4 byte
Enum2, // (int) 4 byte
Enum3, // (int) 4 byte
Enum4 = 5,
Enum5,
Enum6 = 0x7f7f7f7f7f, //(int类型最大值)
Enum7
}MyEnum;
int main() {
printf("%d\n", sizeof(MyEnum)); // 结果:8
printf("%d\n", sizeof(Enum1)); // 结果:8
printf("%d\n", sizeof(Enum2)); // 结果:8
printf("%d\n", sizeof(Enum4)); // 结果:4
printf("%d\n", sizeof(Enum5)); // 结果:4
printf("%d\n", sizeof(Enum6)); // 结果:8
printf("%d\n", sizeof(Enum7)); // 结果:8
return 0;
}
列挙サブ値がint範囲を超えると、列挙バイトは8バイトを占有します。
長い型サイズとして定義された列挙型だと思いましたが、サブ値の出力が正しい値の出力ではなく、それでもオーバーフローしていることがわかりました。
これは、int型のサイズに関連している可能性があります。
(int型について)そのサイズはコンピュータのワード長であり、CPUレジスタの数に関連しています
一般的な状況:32ビットコンピューターは4バイト、64ビットコンピューターは8バイト
ただし、x64コンピューター環境でのデバッグ結果のほとんどは4バイトのままであり、コンパイラーなどのさまざまな条件に関連している可能性があります。
そのような記事は検索データで見つかりました:https://blog.csdn.net/HES_C/article/details/88668276
c言語の記述によれば、それは達成できますが、私はそれを達成できませんでした。他のいくつかの合理的な説明がクエリから得られました:
詳細は以下のとおりです。
1.再版:https://embedded.fm/blog/2016/6/28/how-big-is-an-enum
2.知乎からのメッセージ:
列挙型自体は変数としてメモリに格納されませんが、列挙型自体が変数として使用されます(列挙型の値の指定を含む)。この変数には列挙型の値の一部が含まれているため、スペースが割り当てられます。特定の値のサイズは、マシンの指定された値と列挙値に関連している必要があります。