¿Una variable entera en C ocupa 2 bytes o 4 bytes?
Eso depende de la plataforma que esté utilizando, así como de cómo esté configurado su compilador. La única respuesta autorizada es usar el sizeof
operador para ver qué tan grande es un número entero en su situación específica.
¿Cuáles son los factores de los que depende?
El rango puede ser mejor considerado, en lugar del tamaño . Ambos variarán en la práctica, aunque es mucho más infalible elegir tipos de variables por rango que por tamaño, como veremos. También es importante tener en cuenta que el estándar nos alienta a considerar elegir nuestros tipos enteros en función del rango en lugar del tamaño , pero por ahora ignoremos la práctica estándar y dejemos que nuestra curiosidad explore sizeof
, bytes y CHAR_BIT
, y la representación de enteros ... profundicemos la madriguera del conejo y verlo por nosotros mismos ...
sizeof
, bytes y CHAR_BIT
La siguiente declaración, tomada del estándar C (vinculado a arriba), describe esto en palabras que no creo que puedan mejorarse.
El sizeof
operador produce el tamaño (en bytes) de su operando, que puede ser una expresión o el nombre entre paréntesis de un tipo. El tamaño se determina a partir del tipo de operando.
Asumir una comprensión clara nos llevará a una discusión sobre los bytes . Se supone comúnmente que un byte es de ocho bits, cuando en realidad CHAR_BIT
le dice cuántos bits hay en un byte . Ese es solo otro de esos matices que no se considera cuando se habla de los enteros de dos (o cuatro) bytes comunes .
Vamos a terminar las cosas hasta ahora:
sizeof
=> tamaño en bytes, y
CHAR_BIT
=> número de bits en byte
Por lo tanto, dependiendo de su sistema, sizeof (unsigned int)
podría ser cualquier valor mayor que cero (no solo 2 o 4), como si fuera CHAR_BIT
16, entonces un solo byte (dieciséis bits) tiene suficientes bits para representar el entero de dieciséis bits descrito por el normas (citadas a continuación). Esa no es necesariamente información útil, ¿verdad? Profundicemos más ...
Representación entera
El estándar C especifica la precisión / rango mínimo para todos los tipos enteros estándar (y CHAR_BIT
, también, fwiw) aquí . A partir de esto, podemos derivar un mínimo de cuántos bits se requieren para almacenar el valor , pero también podemos elegir nuestras variables en función de los rangos . Sin embargo, una gran parte de los detalles necesarios para esta respuesta reside aquí. Por ejemplo, lo siguiente que el estándar unsigned int
requiere (al menos) dieciséis bits de almacenamiento:
UINT_MAX 65535 // 2¹⁶ - 1
Por lo tanto, podemos ver que unsigned int
requieren ( al menos ) 16 bits , que es donde obtienes los dos bytes (suponiendo que CHAR_BIT
es 8) ... y más tarde cuando ese límite aumentó a 2³² - 1
, las personas indicaron 4 bytes en su lugar. Esto explica los fenómenos que has observado:
La mayoría de los libros de texto dicen que las variables enteras ocupan 2 bytes. Pero cuando ejecuto un programa que imprime las direcciones sucesivas de una serie de enteros, muestra la diferencia de 4.
Estás utilizando un antiguo libro de texto y un compilador que te está enseñando C no portátil; el autor que escribió su libro de texto puede que ni siquiera lo sepa CHAR_BIT
. Usted debe actualizar su libro de texto (y el compilador), y se esfuerzan por recordar que es un campo en constante evolución que se necesita para mantenerse por delante de la de competir ... basta de eso, sin embargo; veamos qué otros secretos no portátiles almacenan esos bytes enteros subyacentes ...
Los bits de valor son lo que parecen estar contando los conceptos erróneos comunes. El ejemplo anterior utiliza un unsigned
tipo entero que generalmente contiene solo bits de valor, por lo que es fácil pasar por alto al diablo en los detalles.
Bits de signo ... En el ejemplo anterior, cité UINT_MAX
como el límite superior unsigned int
porque es un ejemplo trivial para extraer el valor 16
del comentario. Para los tipos con signo, para distinguir entre valores positivos y negativos (ese es el signo), también debemos incluir el bit de signo.
INT_MIN -32768 // -(2¹⁵)
INT_MAX +32767 // 2¹⁵ - 1
Bits de relleno ... Si bien no es común encontrar computadoras que tienen bits de relleno en enteros, el estándar C permite que eso suceda; algunas máquinas (es decir, esta ) implementan tipos enteros más grandes combinando dos valores enteros más pequeños (con signo) juntos ... y cuando combina enteros con signo, obtiene un bit de signo perdido. Ese bit perdido se considera relleno en C. Otros ejemplos de bits de relleno pueden incluir bits de paridad y bits de captura .
Como puede ver, el estándar parece alentar la consideración de rangos como INT_MIN
... INT_MAX
y otros valores mínimos / máximos del estándar al elegir tipos enteros, y desaconseja depender de los tamaños, ya que hay otros factores sutiles que probablemente se olviden, como los CHAR_BIT
bits de relleno que podría afectar el valor de sizeof (int)
(es decir, los conceptos erróneos comunes de los enteros de dos y cuatro bytes descuidan estos detalles).