pulgadas - ¿Por qué este tamaño de(c+a) está dando 4 byte en lugar de 3
tamaños de discos duros en pulgadas (4)
#include <stdio.h>
int main()
{
short int a;
char c;
printf("%d %d %d",sizeof(a),sizeof(c),sizeof(c+a));
}
En este tamaño de a es de 2 bytes, el tamaño del carácter es de 1 byte, pero los sumo, dan 4 bytes. qué está haciendo dentro de la expresión para que sea 4
Agregar un short int
a un char
resulta en un int
, que aparentemente tiene 4 bytes en su sistema.
Este es un caso si la "promoción de enteros". Consulte En una expresión de C donde están presentes unsigned int y signed int, ¿qué tipo se promocionará a qué tipo? para una explicación Las reglas son bastante confusas, pero las respuestas allí lo explican bastante bien.
Según 6.3.1.8 Conversiones aritméticas habituales del estándar C , la regla de conversión real es:
Si ambos operandos tienen el mismo tipo, entonces no se necesita más conversión.
De lo contrario, si ambos operandos tienen tipos enteros con signo o ambos tienen tipos enteros sin signo, el operando con el tipo de rango de conversión entero menor se convierte al tipo del operando con mayor rango.
De lo contrario, si el operando que tiene un tipo entero sin signo tiene un rango mayor o igual al rango del tipo del otro operando, entonces el operando con tipo entero con signo se convierte al tipo del operando con tipo entero sin signo.
De lo contrario, si el tipo del operando con tipo entero con signo puede representar todos los valores del tipo del operando con tipo entero sin signo, entonces el operando con tipo entero sin signo se convierte al tipo del operando con tipo entero con signo.
De lo contrario, ambos operandos se convierten a los unsigned
tipo entero correspondiente al tipo del operando con tipo de entero con signo.
El resultado es 4, porque, como @WeatherVane señaló en los comentarios:
5.1.2.3 para 11 EJEMPLO 2 Al ejecutar el fragmento char c1, c2; /* ... */ c1 = c1 + c2;
char c1, c2; /* ... */ c1 = c1 + c2;
las "promociones enteras" requieren que la máquina abstracta promueva el valor de cada variable en el tamaño int y luego agregue las dos entradas y trunque la suma. Pero no hay truncamiento aquí porque el destino es desconocido.
Cuando los tipos integrales como char
, short int
, bool
toman menos número de bytes que int
, estos tipos de datos se promocionan automáticamente a int
o unsigned int
cuando se realiza una operación en ellos.
C11 §6.3.1.1 Booleano, caracteres y enteros
Si un int puede representar todos los valores del tipo original (como está restringido por el ancho, para un campo de bit), el valor se convierte en un int; de lo contrario, se convierte a unsigned int. Estas se llaman promociones enteras. 58)
Entonces, c+a
se convierte a tipo int
y el resultado tiene este tipo común de operandos que es int
.
Además, el comportamiento de su código no está definido , porque ha utilizado el especificador de formato incorrecto.
Por lo tanto, use %zu
lugar de %d
porque sizeof()
devuelve size_t
y size_t
unsigned
tiene unsigned
.
Norma C11: §7.21.6.1: Párrafo 9:
Si una especificación de conversión no es válida, el comportamiento no está definido. 225) Si algún argumento no es del tipo correcto para la especificación de conversión correspondiente, el comportamiento no está definido.
Para los matemáticamente inclinados (y porque se me ocurrió preguntarme cuándo tal cosa alguna vez podría ser verdad):
El malentendido de que OP está trabajando es que
f (x) + f (y) = f (x + y)
que ciertamente no es cierto para sizeof()
por las razones que Tom señala en los comentarios.
La clase de funciones para las que es verdadera se llama Additive Maps
Los ejemplos típicos incluyen mapas entre anillos, espacios vectoriales o módulos que conservan el grupo aditivo.
sizeof
devuelve el tamaño de la representación del objeto después de haber sido evaluado. La expresión c+a
aparentemente devuelve un int, que es de cuatro bytes. Creo que lo que estás buscando es:
sizeof(c) + sizeof(a)