[Lenguaje C] Explicación detallada del campo de bits, enumeración y unión

 

Tabla de contenido

1. segmento de bits

1.1 ¿Qué es un segmento de bits?

1.2 Asignación de memoria para segmentos de bits

1.3 Problemas multiplataforma con segmentos de bits

2. Enumeración

2.1 Definición de tipo de enumeración

2.2 Ventajas de la enumeración

3. Unión (comunidad)

3.1 Definición de tipo de unión

3.2 Características de la unión

3.3 Cálculo del tamaño de la junta


1. segmento de bits

1.1 ¿Qué es un segmento de bits?

La declaración de un campo de bits es similar a una estructura, con dos diferencias:

1. Los miembros del campo de bits deben ser int, int sin signo o int con signo.

2. Hay dos puntos y un número después del nombre del miembro del segmento de bits.

Por ejemplo:

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

A es un tipo de segmento de bits. ¿Cuál es el tamaño del segmento A?

printf("%d\n", sizeof(struct A));

 El tamaño del segmento de bits A en VS es de 8 bytes:

Por lo tanto, podemos especular audazmente: el número después de los dos puntos del nombre del miembro del campo de bits representa el tamaño del miembro.

1.2 Asignación de memoria para segmentos de bits

1. Los miembros del segmento de bits pueden ser del tipo int unsigned int firmado int o char (perteneciente a la familia de enteros)

2. El espacio del campo de bits se abre en forma de 4 bytes (int) o 1 byte (char) según la necesidad.

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.

//一个例子
struct S
{
 char a:3;
 char b:4;
 char c:5;
 char d:4;
};
struct S s = {0};
s.a = 10;
s.b = 12;
s.c = 3;
s.d = 4;
//空间是如何开辟的?

El lenguaje C no especifica el método de almacenamiento de la cola y el método de almacenamiento de diferentes compiladores puede ser diferente. 

 Enviamos el resultado al compilador:

printf("%d\n", sizeof(struct S));

Descubrimos que el tamaño de la salida S en el compilador VS es de hecho 3 bytes, y luego verificamos más a fondo:

 A continuación, mediante la depuración del compilador, observe si el valor en la memoria es 620306 estos valores:

 El resultado verificado es correcto.

Por supuesto, la verificación anterior es solo el método de almacenamiento de segmentos de bits en la plataforma VS, y no conocemos otras plataformas.

1.3 Problemas multiplataforma con segmentos de bits

1. No está definido si un campo de bits int se trata como un número con signo o como un número sin signo.

2. No se puede determinar el número máximo de bits en un campo de bits. (Las máquinas de 16 bits pueden tener hasta 16, las máquinas de 32 bits pueden tener hasta 32, escritas como 27, habrá problemas en las máquinas de 16 bits.

3. Aún no se ha definido si los miembros en el segmento de bits se asignan de izquierda a derecha en la memoria o de derecha a izquierda.

4. Cuando una estructura contiene dos segmentos de bits y el segundo segmento de bits es demasiado grande para acomodar los bits restantes del primer segmento de bits, no está claro si descartar los bits restantes o utilizarlos.

Resumir:

En comparación con las estructuras, los campos de bits pueden lograr el mismo efecto y pueden ahorrar mucho espacio, pero existen problemas multiplataforma.

2. Enumeración

La enumeración, como su nombre indica, consiste en enumerar uno por uno.

Enumere todos los valores posibles.

Por ejemplo en nuestra vida real:

Solo hay 7 días a la semana de lunes a domingo, que se pueden enumerar uno por uno.

Género: masculino, femenino, confidencial y también se pueden enumerar uno por uno.

Hay 12 meses en el mes y también puedes enumerarlos uno por uno.

Aquí se pueden utilizar enumeraciones.

2.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
};

Los enum Day , enum Sex y enum Color definidos anteriormente son todos tipos de enumeración. El contenido de {} es el valor posible del tipo de enumeración, también llamado constante de enumeración. Todos estos valores posibles son válidos, comenzando desde 0 de forma predeterminada y aumentando en 1 a su vez.

Tomemos el color como ejemplo:

enum Color//颜色
{
	RED,
	GREEN,
	BLUE
};
int main()
{
	printf("%d\n", RED);
	printf("%d\n", GREEN);
	printf("%d\n", BLUE);
	return 0;
}

 Por supuesto, el valor inicial también se puede asignar al declarar el tipo de enumeración. Por ejemplo:

enum Color//颜色
{
	RED = 1,
	GREEN = 2,
	BLUE = 4
};

 Modifique el valor predeterminado:

 

2.2 Ventajas de la enumeración

¿Por qué utilizar enumeraciones?

Podemos usar #define para definir constantes, ¿por qué usar enumeraciones?

Ventajas de las enumeraciones:

  1. Aumentar la legibilidad y mantenibilidad del código
  2. En comparación con el identificador definido por #define, la enumeración tiene verificación de tipo, que es más rigurosa.
  3. Fácil de depurar
  4. Fácil de usar, puede definir múltiples constantes a la vez

3. Unión (comunidad)

3.1 Definición de tipo de unión

Unión también es un tipo personalizado especial. La variable definida por este tipo también contiene una serie de miembros, y la característica es que estos miembros comparten el mismo espacio (por lo que unión también se llama unión) . Por ejemplo:

union Un
{
	char c;
	int i;
};

3.2 Características de la unión

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

union Un
{
	char c;
	int i;
};
int main()
{
	printf("%d\n", sizeof(union Un));
	return 0;
}

 Los sindicalistas comparten el mismo espacio de memoria:

 Preguntas de entrevista:

Escriba un programa para juzgar el tamaño y el tamaño de la computadora actual.

 Hemos escrito un código similar a este antes para juzgar:

int main()
{
	int a = 1;
	if (*(char*)&a == 1)
	{
		printf("小端存储\n");
	}
	else
	{
		printf("大端存储\n");
	}
	return 0;
}

Ahora también podemos usar la unión para juzgar:

int check_system()
{
	union
	{
		int i;
		char c;
	}un = { .i = 1 };
	return un.c;
}
int main()
{
	int ret = check_system();
	if (ret == 1)
	{
		printf("小端存储\n");
	}
	else
	{
		printf("大端存储\n");
	}
	return 0;
}

3.3 Cálculo del tamaño de la junta

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

Por ejemplo:

union Un1
{
	char c[5];
	int i;
};
union Un2
{
	short c[7];
	int i;
};
int main()
{
	printf("%d\n", sizeof(union Un1));
	printf("%d\n", sizeof(union Un2));
	return 0;
}

 

Supongo que te gusta

Origin blog.csdn.net/m0_73648729/article/details/132422624
Recomendado
Clasificación