¿Una variable entera en C ocupa 2 bytes o 4 bytes? ¿Cuáles son los factores de los que depende?
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.
int
es solo uno de varios tipos enteros . Usted preguntó sobre el tamaño de "entero"; probablemente querías preguntar sobre el tamaño deint
.int
es de 2 bytes (a) probablemente se refiere a un sistema antiguo y (b) no deja en claro que el tamaño variará de un sistema a otro. El mejor libro sobre C es "El lenguaje de programación C" de Kernighan y Ritchie, aunque supone algo de experiencia en programación. Ver también la pregunta 18.10 de la FAQ comp.lang.c .#define int int64_t
en una plataforma de 64 bits, así que tampoco. Solo úsalosizeof
. ;-)Respuestas:
Sé que es igual a
sizeof(int)
. El tamaño de unint
es realmente dependiente del compilador. En el pasado, cuando los procesadores eran de 16 bits, unint
era de 2 bytes. Hoy en día, con mayor frecuencia son 4 bytes en sistemas de 32 bits y de 64 bits.Aún así, usar
sizeof(int)
es la mejor manera de obtener el tamaño de un número entero para el sistema específico en el que se ejecuta el programa.EDITAR: Se corrigió una declaración incorrecta que
int
es de 8 bytes en la mayoría de los sistemas de 64 bits. Por ejemplo, son 4 bytes en GCC de 64 bits.fuente
sizeof(int)
puede ser cualquier valor de1
. No se requiere que un byte sea de 8 bits y algunas máquinas no tienen una unidad direccionable de 8 bits (que básicamente es la definición de un byte en el estándar). La respuesta no es correcta sin más información.Este es uno de los puntos en C que puede ser confuso al principio, pero el estándar C solo especifica un rango mínimo para tipos enteros que se garantiza que es compatible.
int
se garantiza que puede contener -32767 a 32767, lo que requiere 16 bits. En ese casoint
, es de 2 bytes. Sin embargo, las implementaciones son libres de ir más allá de ese mínimo, ya que verá que muchos compiladores modernos hacenint
32 bits (lo que también significa 4 bytes bastante ubicuamente).La razón por la que su libro dice 2 bytes es probablemente porque es antigua. En un momento, esta era la norma. En general, siempre debe usar el
sizeof
operador si necesita averiguar cuántos bytes hay en la plataforma que está usando.Para abordar esto, C99 agregó nuevos tipos donde puede solicitar explícitamente un número entero de cierto tamaño, por ejemplo
int16_t
oint32_t
. Antes de eso, no había una forma universal de obtener un número entero de un ancho específico (aunque la mayoría de las plataformas proporcionaban tipos similares por plataforma).fuente
int
. C no hace esa suposición. El complemento de 1 y los sistemas de magnitud de signo no pueden representar-32768
en 16 bits; más bien, tienen dos representaciones para cero (positivo y negativo). Es por eso que el rango mínimo para unint
es[-32767..32767]
.No hay una respuesta específica. Depende de la plataforma. Está definido por la implementación. Puede ser 2, 4 o algo más.
La idea detrás
int
era que se suponía que debía coincidir con el tamaño natural de "palabra" en la plataforma dada: 16 bits en plataformas de 16 bits, 32 bits en plataformas de 32 bits, 64 bits en plataformas de 64 bits, se entiende la idea. Sin embargo, para fines de compatibilidad con versiones anteriores, algunos compiladores prefieren mantener 32 bitsint
incluso en plataformas de 64 bits.Sin
int
embargo, el tiempo de 2 bytes ya pasó (¿plataformas de 16 bits?) A menos que esté utilizando alguna plataforma integrada con un tamaño de palabra de 16 bits. Tus libros de texto son probablemente muy viejos.fuente
The idea behind int was that it was supposed to match the natural "word" size on the given platform
- Esto es lo que estaba buscando. ¿Alguna idea de cuál puede ser la razón? En un mundo libre, int podría ocupar cualquier número de bytes consecutivos en la memoria, ¿verdad? 8, 16 lo que seaLa respuesta a esta pregunta depende de la plataforma que esté utilizando.
Pero independientemente de la plataforma, puede asumir de manera confiable los siguientes tipos:
fuente
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.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 yCHAR_BIT
, y la representación de enteros ... profundicemos la madriguera del conejo y verlo por nosotros mismos ...sizeof
, bytes yCHAR_BIT
La siguiente declaración, tomada del estándar C (vinculado a arriba), describe esto en palabras que no creo que puedan mejorarse.
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, yCHAR_BIT
=> número de bits en bytePor lo tanto, dependiendo de su sistema,
sizeof (unsigned int)
podría ser cualquier valor mayor que cero (no solo 2 o 4), como si fueraCHAR_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ándarunsigned int
requiere (al menos) dieciséis bits de almacenamiento:Por lo tanto, podemos ver que
unsigned int
requieren ( al menos ) 16 bits , que es donde obtienes los dos bytes (suponiendo queCHAR_BIT
es 8) ... y más tarde cuando ese límite aumentó a2³² - 1
, las personas indicaron 4 bytes en su lugar. Esto explica los fenómenos que has observado: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 superiorunsigned int
porque es un ejemplo trivial para extraer el valor16
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.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 losCHAR_BIT
bits de relleno que podría afectar el valor desizeof (int)
(es decir, los conceptos erróneos comunes de los enteros de dos y cuatro bytes descuidan estos detalles).fuente
C99 N1256 borrador estándar
http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
El tamaño de
int
y todos los demás tipos enteros están definidos por la implementación, C99 solo especifica:5.2.4.2.1 "Tamaños de tipos enteros
<limits.h>
" da los tamaños mínimos:6.2.5 "Tipos" luego dice:
y 6.3.1.1 "Booleanos, caracteres y enteros" determina los rangos de conversión relativos:
fuente
Las únicas garantías son que
char
debe tener al menos 8 bits de ancho,short
yint
debe tener al menos 16 bits de ancho, ylong
debe tener al menos 32 bits de ancho, y quesizeof (char)
<=sizeof (short)
<=sizeof (int)
<=sizeof (long)
(lo mismo es cierto para las versiones sin signo de esos tipos )int
puede tener entre 16 y 64 bits de ancho, dependiendo de la plataforma.fuente
La respuesta es "sí" / "no" / "tal vez" / "tal vez no".
El lenguaje de programación C especifica lo siguiente: la unidad direccionable más pequeña, conocida
char
y también llamada "byte" , tiene exactamente unaCHAR_BIT
anchura de bits, dondeCHAR_BIT
tiene al menos 8.Entonces, un byte en C no es necesariamente un octeto , es decir, 8 bits. En el pasado, una de las primeras plataformas en ejecutar código C (y Unix) tenía 4 bytes
int
, pero en totalint
tenía 36 bits, ¡porqueCHAR_BIT
era 9!int
se supone que es el tamaño entero natural para la plataforma que tiene un rango de al menos-32767 ... 32767
. Puede obtener el tamaño deint
los bytes de la plataforma consizeof(int)
; Cuando multiplique este valor porCHAR_BIT
, sabrá qué tan ancho es en bits.Si bien las máquinas de 36 bits están en su mayoría muertas, todavía hay plataformas con bytes que no son de 8 bits. Justo ayer hubo una pregunta sobre una MCU de Texas Instruments con bytes de 16 bits , que tiene un compilador compatible con C99, C11.
En TMS320C28x parece que
char
,short
yint
son todos de 16 bits de ancho, y por lo tanto un byte.long int
es de 2 bytes ylong long int
es de 4 bytes. La belleza de C es que aún se puede escribir un programa eficiente para una plataforma como esta, ¡e incluso hacerlo de manera portátil!fuente
Principalmente depende de la plataforma que esté utilizando. Depende del compilador al compilador. Actualmente, en la mayoría de los compiladores int es de 4 bytes . Si desea verificar qué está usando su compilador, puede usarlo
sizeof(int)
.Lo único que promete el compilador de c es que el tamaño de short debe ser igual o menor que int y el tamaño de long debe ser igual o mayor que int. Entonces, si el tamaño de int es 4, entonces el tamaño de short puede ser 2 o 4 pero no mayor que eso. Lo mismo es cierto por mucho tiempo e int. También dice que el tamaño de corto y largo no puede ser el mismo.
fuente
%d
para unsize_t
parámetro es UB.Esto depende de la implementación, pero generalmente en x86 y otras arquitecturas populares como ARM
int
s toman 4 bytes. Siempre puede verificar en tiempo de compilación utilizandosizeof(int)
o cualquier otro tipo que desee verificar.Si desea asegurarse de usar un tipo de un tamaño específico, use los tipos en
<stdint.h>
fuente
Esto devuelve 4, pero probablemente depende de la máquina.
fuente
C permite que "bytes" sean algo más que 8 bits por "byte".
Un valor de algo más que 8 es cada vez menos común. Para una portabilidad máxima, use en
CHAR_BIT
lugar de 8. El tamaño de unint
en bits en C essizeof(int) * CHAR_BIT
.El
int
tamaño de bit es comúnmente de 32 o 16 bits. C rangos mínimos especificados :El rango mínimo para
int
obliga a que el tamaño de los bits sea de al menos 16, incluso si el procesador era de "8 bits". Un tamaño como 64 bits se ve en procesadores especializados. Otros valores como 18, 24, 36, etc. han ocurrido en plataformas históricas o son al menos teóricamente posibles. La codificación moderna rara vez se preocupa por losint
tamaños de 2 bits sin potencia .El procesador y la arquitectura de la computadora controlan la
int
selección del tamaño de bits.Sin embargo, incluso con procesadores de 64 bits, el
int
tamaño del compilador puede ser de 32 bits por razones de compatibilidad, ya que las bases de código grandes dependen deint
ser de 32 bits (o 32/16).fuente
Esta es una buena fuente para responder esta pregunta.
Pero esta pregunta es una especie de verdad siempre y fue "Sí. Ambas".
Depende de tu arquitectura. Si va a trabajar en una máquina de 16 bits o menos, no puede ser de 4 bytes (= 32 bits). Si está trabajando en una máquina de 32 bits o mejor, su longitud es de 32 bits.
Para averiguarlo, prepare su programa para generar algo legible y use la función "sizeof". Eso devuelve el tamaño en bytes de su tipo de datos declarado. Pero tenga cuidado al usar esto con matrices.
Si está declarando
int t[12];
, devolverá 12 * 4 bytes. Para obtener la longitud de esta matriz, solo usesizeof(t)/sizeof(t[0])
. Si va a construir una función, que debería calcular el tamaño de una matriz de envío, recuerde que siEntonces esto ni siquiera devolverá algo diferente. Si define una matriz e intenta obtener la longitud después, use sizeof. Si envía una matriz a una función, recuerde que el valor de envío es solo un puntero en el primer elemento. Pero en el primer caso, siempre se sabe qué tamaño tiene su matriz. El caso dos se puede resolver definiendo dos funciones y perder algo de rendimiento. Defina la función (matriz t) y defina la función2 (matriz t, int size_of_t). Llame a "función (t)", mida la longitud mediante algún trabajo de copia y envíe el resultado a function2, donde puede hacer lo que quiera en tamaños de matriz variables.
fuente
char
siempre lo essigned
)