Menu

Tipos de datos en C: int, float, char, double y más

Cada variable de C tiene un tipo que fija su tamaño y lo que puede guardar. Aquí están todos los tipos básicos, sus tamaños reales, con signo frente a sin signo, sizeof, limits.h y qué pasa en un desbordamiento.

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

Cada variable en C tiene un tipo, elegido cuando la declaras y fijo durante toda su vida. El tipo decide tres cosas: cuántos bytes ocupa la variable, cómo se interpretan esos bytes y qué operaciones tienen sentido sobre ella.

La lista de tipos de C es corta. La complejidad está en los modificadores.

Los cuatro tipos base

  • char guarda un byte. Se usa para caracteres individuales ('A'), para los bytes de una cadena y a veces como un entero diminuto.
  • int es el tipo de número entero de uso general. Contadores de bucles, tamaños, identificadores.
  • float y double guardan números reales. double tiene aproximadamente el doble de precisión.
  • void es el cuarto tipo en cierto sentido, pero significa "sin valor": no puedes declarar una variable void, solo usarlo como tipo de retorno de una función, como lista de parámetros vacía o como puntero sin tipo.

Fíjate en el sufijo f de 3.14f. Sin él el literal es un double, y asignarlo a un float pierde precisión en silencio. Algunos compiladores lo advierten.

Modificadores: short, long, unsigned

Los tipos enteros base vienen con modificadores que cambian el tamaño o el signo.

Cada tipo entero necesita su propio especificador de formato: %hd para short, %d para int, %ld para long, %lld para long long, %u para unsigned. Usar el equivocado es comportamiento indefinido, no un error de redondeo.

unsigned elimina el bit de signo y duplica el rango positivo. Un unsigned int guarda de 0 a unos 4.300 millones en lugar de -2.100 a +2.100 millones. Es la elección correcta para cosas que genuinamente no pueden ser negativas — tamaños, conteos de bytes, patrones de bits — y una trampa para cualquier cosa a la que se le pueda restar por debajo de cero.

signed es el valor por defecto para int, short, long y long long, así que casi nunca lo escribes. El único lugar donde importa es char: si un char simple es con signo o sin signo queda definido por la implementación, así que escribe signed char o unsigned char cuando el signo importe.

Tamaños: lo que realmente obtienes

El estándar de C especifica mínimos, no tamaños exactos. En cualquier máquina moderna de 64 bits con Linux, macOS o Windows verás esto:

TipoTamaño típicoRango típico
char1 byte-128 a 127 (o 0 a 255)
short2 bytes-32.768 a 32.767
int4 bytes-2.147.483.648 a 2.147.483.647
long8 bytes (4 en Windows)aproximadamente ±9,2 trillones
long long8 bytesaproximadamente ±9,2 trillones
float4 bytes~7 dígitos significativos
double8 bytes~15 dígitos significativos
long double16 bytes (varía)más que double

La fila de long es la que agarra desprevenida a la gente: son 8 bytes en Linux y macOS, y 4 bytes en Windows de 64 bits. El código que asume que long puede guardar un valor de 64 bits no es portable. Usa long long, o los tipos de ancho exacto de stdint.h (int32_t, uint64_t) cuando el tamaño sea parte del requisito.

sizeof: pregúntale al compilador

Nunca adivines un tamaño: mídelo.

sizeof es un operador, no una función, y se evalúa en tiempo de compilación. Produce un valor de tipo size_t, que se imprime con %zu.

sizeof(char) está garantizado que es exactamente 1: esa es la definición de byte en C. Todo lo demás se mide en relación con eso.

limits.h y float.h

Los rangos exactos de tu compilador están disponibles como constantes con nombre:

Estos son los valores con los que comparar cuando necesitas saber si una operación se va a desbordar. Comprobar if (a > INT_MAX - b) antes de calcular a + b es la forma de detectar el desbordamiento antes de que ocurra, lo cual importa, porque no puedes detectar el desbordamiento con signo después.

Desbordamiento de enteros

Qué pasa cuando un valor excede el rango de su tipo depende por completo del signo.

El desbordamiento sin signo está definido: el valor da la vuelta módulo 2^N.

Ese segundo caso es una fuente real de errores. Un bucle como for (unsigned i = n - 1; i >= 0; i--) nunca termina, porque un valor sin signo siempre es >= 0.

El desbordamiento con signo es comportamiento indefinido. No "da la vuelta": indefinido. Al compilador se le permite asumir que nunca ocurre y optimizar sobre esa base, lo que significa que una comprobación de desbordamiento escrita después del hecho puede ser eliminada:

int sum = a + b;
if (sum < a) { /* el compilador puede eliminar esto por completo */ }

Compruébalo antes, usando los límites:

if (b > 0 && a > INT_MAX - b) {
    /* a + b se desbordaría: manéjalo */
}

Precisión de punto flotante

float y double guardan los números en binario, y la mayoría de las fracciones decimales no tienen forma binaria exacta, de la misma manera que 1/3 no tiene forma decimal exacta.

La regla que se deduce: nunca compares valores de punto flotante con ==. Compara en cambio la diferencia absoluta contra una tolerancia pequeña.

Y nunca uses punto flotante para dinero. Guarda los centavos como un entero; un long long de centavos es exacto donde un double de pesos no lo es.

Elegir un tipo

Una lista corta de decisiones que cubre la mayor parte del código:

  • Números enteros: int a menos que tengas una razón. Es el tipo que la CPU maneja con más eficiencia y el tipo alrededor del cual están construidas todas las reglas aritméticas.
  • Cualquier cosa mayor a 2.000 millones: long long, o int64_t de stdint.h.
  • Tamaños, longitudes e índices de arrays provenientes de sizeof o strlen: size_t. Es sin signo y está garantizado que es lo bastante grande para cualquier objeto.
  • Decimales: double. Usa float solo para reducir a la mitad la memoria en arrays grandes o en hardware embebido sin unidad de doble precisión.
  • Caracteres individuales y bytes crudos: char para texto, unsigned char para datos binarios.
  • Verdadero/falso: bool de stdbool.h — mira booleanos en C.
  • Anchos de bits exactos (formatos de archivo, protocolos de red, registros de hardware): stdint.huint8_t, int16_t, uint32_t, y así sucesivamente.

Mezclar tipos

Cuando combinas dos tipos distintos en una misma expresión, C los convierte a tus espaldas antes de hacer la aritmética. Eso suele ser útil y ocasionalmente desastroso:

La primera es división entera: ambos operandos son int, así que el resultado es un int y la fracción se descarta. La tercera es peor: comparar un valor con signo con uno sin signo convierte el que tiene signo a sin signo, convirtiendo -1 en un número positivo enorme.

Esas reglas de conversión, y cómo tomar el control de ellas con conversiones explícitas, son el tema de conversión de tipos en C.

Preguntas frecuentes

¿Cuáles son los tipos de datos básicos en C?

Cuatro tipos base: char para caracteres individuales y bytes, int para números enteros, y float y double para decimales. Los modificadores cambian su tamaño y su signo — short, long, long long, signed y unsigned — produciendo el conjunto completo.

¿Cuántos bytes ocupa un int en C?

Casi siempre 4 bytes (32 bits) en sistemas modernos de escritorio y servidores, lo que da un rango de aproximadamente -2.100 millones a 2.100 millones. El estándar solo garantiza al menos 2 bytes, y los microcontroladores de 16 bits sí usan 2. Usa sizeof(int) si necesitas saberlo con certeza.

¿Cuál es la diferencia entre float y double en C?

float ocupa 4 bytes con alrededor de 7 dígitos decimales significativos; double ocupa 8 bytes con unos 15. Double es el tipo por defecto de los literales de punto flotante y de las funciones matemáticas, y salvo que estés guardando millones de valores o apuntando a un chip embebido, double es la elección correcta.

¿Qué pasa cuando un int se desborda en C?

Para un int con signo, el desbordamiento es comportamiento indefinido: el compilador puede dar la vuelta, saturar o eliminar por completo la comprobación al optimizar. Para un int sin signo está totalmente definido: el valor da la vuelta módulo 2^N, así que UINT_MAX + 1 es 0. Nunca te apoyes en el desbordamiento con signo.

Coddy programming languages illustration

Aprende a programar con Coddy

COMENZAR