データ構造タイプ(メモリ記事)

データ構造型(メモリの章)超完全構造、共用体、列挙型メモリ解釈(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.知乎からのメッセージ:

ここに画像の説明を挿入

列挙型自体は変数としてメモリに格納されませんが、列挙型自体が変数として使用されます(列挙型の値の指定を含む)。この変数には列挙型の値の一部が含まれているため、スペースが割り当てられます。特定の値のサイズは、マシンの指定された値と列挙値に関連している必要があります。

おすすめ

転載: blog.csdn.net/zhuiyizhifengfu/article/details/113063937