Aprendizaje profundo "Tipo personalizado: estructura, enumeración, unión (C / C ++)"

Tipos personalizados: estructura, enumeración, unión

1. Estructura
(1) La declaración de la estructura

Una estructura es una colección de valores y estos valores se denominan variables miembro. Cada miembro de la estructura puede ser una variable de diferente tipo.

struct stu//描述一个学生
{
    
    
 char name[20];//名字
 int age;//年龄
 char sex[5];//性别
 char id[20];//学号
}//分号不能丢
(2) Autorreferencia de la estructura

¿Está bien incluir un miembro cuyo tipo sea la estructura misma en la estructura?

//代码1
struct Node
{
    
    
 int data;
 struct Node next;
};
//可行否?
如果可以,那sizeof(struct Node)是多少?

La forma correcta de autorreferenciarse:

//代码2
struct Node
{
    
    
 int data;
 struct Node* next;
};

Nota:

//代码3
typedef struct
{
    
    
 int data;
 Node* next; }Node;
//这样写代码,可行否?

//解决方案:
typedef struct Node
{
    
    
 int data;
 struct Node* next; }Node;
(3) Definición e inicialización de variables de estructura
struct Point
{
    
    
 int x;
 int y; }p1; //声明类型的同时定义变量p1
struct Point p2; //定义结构体变量p2
//初始化:定义变量的同时赋初值。
struct Point p3 = {
    
    x, y};
struct Stu        //类型声明
{
    
    
 char name[15];//名字
 int age;      //年龄
};
struct Stu s = {
    
    "zhangsan", 20};//初始化
struct Node
{
    
    
 int data;
 struct Point p;
 struct Node* next; 
}n1 = {
    
    10, {
    
    4,5}, NULL}; //结构体嵌套初始化
struct Node n2 = {
    
    20, {
    
    5, 6}, NULL};//结构体嵌套初始化
(4) Alineación de la memoria de la estructura

Calcule el tamaño de la estructura:

//练习1
struct S1
{
    
    
 char c1;
 int i;
 char c2;
};
printf("%d\n", sizeof(struct S1)); //12字节
//练习2
struct S2
{
    
    
 char c1;
 char c2;
 int i;
};
printf("%d\n", sizeof(struct S2));//8字节
//练习3
struct S3
{
    
    
 double d;
 char c;
 int i;
};
printf("%d\n", sizeof(struct S3));//16字节
//练习4-结构体嵌套问题
struct S4
{
    
    
 char c1;
 struct S3 s3;
 double d;
};
printf("%d\n",sizeof(struct S4));//32字节

¿Como calcular?

  1. El primer miembro está en una dirección con un desplazamiento de 0 de la variable de estructura.
  2. Otras variables miembro deben alinearse con una dirección que sea un múltiplo entero de un cierto número (número de alineación).
    Número de alineación = el valor más pequeño del número de alineación predeterminado del compilador y el tamaño del miembro .
    El valor predeterminado en VS es 8
  3. El tamaño total de la estructura es un múltiplo entero del número máximo de alineación (cada variable miembro tiene un número de alineación).
  4. Si la estructura está anidada, la estructura anidada se alinea con un múltiplo entero de su alineación máxima y el tamaño total de la estructura es un múltiplo entero de todas las alineaciones máximas (incluida la alineación de las estructuras anidadas).

¿Por qué hay alineación de la memoria?

1. Motivo de la plataforma (motivo del trasplante): no todas las plataformas de hardware pueden acceder a los datos en cualquier dirección; algunas plataformas de hardware solo pueden obtener ciertos tipos de datos en determinadas direcciones; de lo contrario, se lanzará una excepción de hardware.
2. Razones de rendimiento: las estructuras de datos (especialmente las pilas) deben alinearse con los límites naturales tanto como sea posible. La razón es que para acceder a la memoria no alineada, el procesador necesita realizar dos accesos a la memoria, mientras que el acceso a la memoria alineada solo requiere un acceso.

En general:

La alineación de memoria de la estructura es la práctica de intercambiar espacio por tiempo .

Al diseñar la estructura, no solo debemos satisfacer la alineación, sino también ahorrar espacio, cómo hacerlo:

Deje que los miembros que ocupan un pequeño espacio se reúnan tanto como sea posible.

(5) Modificar el número de alineación predeterminado
#include <stdio.h>
#pragma pack(8)//设置默认对齐数为8 struct S1
{
    
    
char c1; int i; char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认

#pragma pack(1)//设置默认对齐数为8 struct S2
{
    
    
char c1; int i; char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认int main()
{
    
    
//输出的结果是什么?
printf("%d\n", sizeof(struct S1)); printf("%d\n", sizeof(struct S2)); return 0;
}

En conclusión:

Cuando la alineación de la estructura es inapropiada, podemos cambiar la alineación predeterminada por nosotros mismos.

(6) Rango

La declaración y la estructura de los segmentos de bits son similares, con dos diferencias:

1. Los miembros del segmento de bits deben ser int, unsigned int oigned int.
2. Hay dos puntos y un número después del nombre de miembro del segmento de bits.

tal como:

struct A
{
    
    
int _a:2; 
int _b:5; 
int _c:10; 
int _d:30;
};

Asignación de memoria

1. Los miembros del segmento de bits pueden ser int unsigned \ intigned \ int o char (perteneciente a la familia de enteros) tipo
2. El espacio del segmento de bits es de 4 bytes (int) o 1 byte (char) según sea necesario. para abrirse.
3. Los segmentos de bits implican muchos factores inciertos. Los segmentos de bits no son multiplataforma. Los programas que se centran en la portabilidad deben evitar el uso de segmentos de bits.

Problemas multiplataforma

1. No se sabe si el campo de bits int se considera un número con signo o sin signo.
2. No se puede determinar el número de bits más grandes en el segmento de bits. (Las máquinas de 16 bits tienen un máximo de 16, las máquinas de 32 bits tienen un máximo de 32, escrito como 27, habrá problemas en las máquinas de 16 bits.
3. Los miembros en el segmento de bits se asignan de izquierda a derecha en la memoria, o el estándar para la asignación de derecha a izquierda no se ha definido.
4. Cuando una estructura contiene dos segmentos de bits, y el segundo segmento de bits tiene un miembro relativamente grande y no puede caber en los bits restantes del primer segmento de bits, no se sabe si descartar los bits restantes o utilizarlos.

Aplicación de segmento de bits
Inserte la descripción de la imagen aquí

Dos, enumeración
(1) Definición de tipo de enumeración
enum Day//星期
{
    
    
Mon, Tues, Wed, Thur, Fri, Sat, Sun
};
enum Sex//性别
{
    
    
MALE, FEMALE, SECRET
}enum Color//颜色
{
    
    
RED, GREEN, BLUE
};
(2) Ventajas de la enumeración

1. Incrementar la legibilidad y mantenibilidad del código
2. Comparado con el identificador definido por #definir, la enumeración tiene verificación de tipo, que es más rigurosa.
3. Evita la contaminación de nombres (encapsulación)
4. Fácil de depurar
5. Fácil de usar, se pueden definir múltiples constantes a la vez

(3) El uso de la enumeración
enum Color//颜色
{
    
    
RED=1, GREEN=2, BLUE=4
};
enum Color clr = GREEN;//只能拿枚举常量给枚举变量赋值,才不会出现类型的差异。clr = 5;	//ok??
3. Conjunto (unión)
(1) Definición de tipo de unión

La unión también es un tipo personalizado especial. Las variables definidas por este tipo también contienen una serie de miembros. La característica es que estos miembros comparten el mismo espacio (por lo que la unión también se llama unión). tal como:

//联合类型的声明union Un
{
    
    
char c; int i;
};

//联合变量的定义union Un un;
//计算连个变量的大小printf("%d\n", sizeof(un));
(2) Las características de la articulación

Los miembros de la unión comparten el mismo espacio de memoria El tamaño de dicha variable de unión es al menos el tamaño del miembro más grande (porque la unión debe al menos poder almacenar el miembro más grande).

(3) Cálculo del tamaño de la junta

1. El tamaño de la unión es al menos el tamaño del miembro más grande.
2. Cuando el tamaño máximo del miembro no es un múltiplo integral de la alineación máxima, debe alinearse a un múltiplo integral de la alineación máxima.

tal como:

union Un1
{
    
    
char c[5]; 
int i;
};
union Un2
{
    
    
short c[7]; 
int i;
};
// 下 面 输 出 的 结 果 是 什 么 ? 
printf("%d\n", sizeof(union Un1));//8字节
 printf("%d\n", sizeof(union Un2));//16字节

Supongo que te gusta

Origin blog.csdn.net/qq_47364122/article/details/110226123
Recomendado
Clasificación