Tipo de estructura de datos (artículos de memoria)

Tipos de estructura de datos (artículos de memoria) estructura súper completa, unión, interpretación de memoria de enumeración (aplicable a la entrada en lenguaje C)

1. La memoria de la estructura

Alineación de la memoria

regla:

1. La dirección donde se almacena el primer miembro de datos de la estructura es la dirección donde el desplazamiento de la variable de estructura es 0.

2. La otra dirección inicial es un múltiplo entero de la memoria ocupada por este tipo de variable, si la parte insuficiente se llena con datos a un múltiplo entero de la memoria ocupada

3. La memoria total ocupada por la estructura es un múltiplo entero del número máximo de bytes del tipo de datos básicos en los miembros de la estructura.

(Ver diagrama 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;
}
Gráfico 1-1

Inserte la descripción de la imagen aquí

Si la estructura contiene una matriz: (vea la Figura 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;
}
Ilustración 1-2

Inserte la descripción de la imagen aquí

Si la estructura contiene una estructura:

#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;
}

Conclusión: La estructura str6 y str7 son equivalentes, cuando los miembros de la estructura contienen la estructura, es equivalente a expandir el contenido de la estructura del miembro.

Nota: ¡La estructura contenida en un miembro de estructura no puede ser ella misma!

[El código completo es el siguiente]
#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. Memoria del consorcio

regla:

1. El tamaño debe ser lo suficientemente grande para acomodar el miembro más ancho
2. El tamaño puede ser divisible por el tamaño de todos los tipos de datos básicos que contiene

#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. Memoria enumerada

#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;
}

La mayoría de las explicaciones sobre la enumeración son: la enumeración es de 4 bytes; (ejemplo: la situación anterior)

——El problema de enumerar la memoria no tiene por qué ser demasiado profundo, pero quiero explorarlo.

La descripción del lenguaje C estándar no especifica claramente el tamaño del espacio ocupado por el tipo de enumeración, lo que significa: "El tamaño del tipo de enumeración es el tamaño del número entero que puede acomodar el subvalor de enumeración más grande". time, el estándar también establece: "En el tipo de enumeración, el valor de la subenumeración debe poder usar una expresión 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;
}

Cuando el subvalor de enumeración excede el rango int, el byte de enumeración ocupa 8 bytes

Pensé que era una enumeración definida como un tamaño de letra largo, pero descubrí que la salida del subvalor no es la salida del valor correcto y aún se desborda;

Esto puede estar relacionado con el tamaño del tipo int:

(Acerca del tipo int) Su tamaño es la longitud de la palabra de la computadora, que está relacionada con el número de registros de la CPU

Situación general: la computadora de 32 bits tiene 4 bytes, la computadora de 64 bits tiene 8 bytes

Sin embargo, la mayoría de los resultados de depuración en el entorno informático x64 siguen siendo de 4 bytes, lo que puede estar relacionado con diversas condiciones, como el compilador.

Dicho artículo se encontró en los datos de búsqueda: https://blog.csdn.net/HES_C/article/details/88668276

Según la descripción del lenguaje c, se puede lograr, pero no lo logré. Algunas otras explicaciones razonables se obtuvieron de la consulta:

Los detalles son los siguientes:

1. Reimpresión: https://embedded.fm/blog/2016/6/28/how-big-is-an-enum

2. Mensaje de Zhihu:

Inserte la descripción de la imagen aquí

La enumeración en sí no se almacena en la memoria como una variable, pero la enumeración en sí se usa como una variable (incluida la especificación de qué valor de enumeración es), porque esta variable contiene una parte del valor en el tipo de enumeración, por lo que se asignará espacio. específico El tamaño del valor debe estar relacionado con el valor especificado de la máquina y el valor de enumeración.

Supongo que te gusta

Origin blog.csdn.net/zhuiyizhifengfu/article/details/113063937
Recomendado
Clasificación