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
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
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:
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.