</>waridocu

C++

Variables, tipos de datos y operadores

Cómo se declaran variables en C++, qué tipos fundamentales existen y qué hacen los operadores básicos.

cppvariablestiposoperadoresconstauto

De dónde venimos

En ¿Qué es C++? escribiste un programa que solo imprimía texto fijo, y en La Standard Library y tu primer main() apareció la primera variable de verdad:

Recordando: la variable de la página anteriorcpp
std::string nombre;
std::cin >> nombre;

Ahí se coló mucha información sin explicar: por qué hay que escribir std::string antes del nombre, qué significa esa línea a nivel de memoria, y qué otros tipos existen además de std::string. Esta página cierra ese hueco. Todo lo que viene después en esta sección (control de flujo, funciones, punteros) se apoya en entender bien qué es una variable en C++.

Qué es una variable

Una variable es un espacio con nombre dentro de la memoria del programa, que guarda un valor de un tipo concreto. En C++ una variable tiene siempre tres cosas:

  1. Un tipo (int, double, std::string…), decidido al escribirla y que ya no cambia.
  2. Un nombre para referirte a ella.
  3. Una dirección de memoria donde vive físicamente el valor.

Ese tercer punto parece un detalle irrelevante ahora, pero es exactamente lo que vas a necesitar cuando lleguemos a punteros: un puntero no es más que una variable que guarda la dirección de otra.

C++ es de tipado estático: el tipo se fija cuando compilas, no cuando ejecutas. Si declaras int edad;, esa variable jamás podrá contener texto. El compilador lo verifica y falla antes de generar el programa, que es justamente lo que lo hace rápido en tiempo de ejecución.

Ejemplo: declarar e inicializar variablescpp
#include <iostream>
#include <string>

int main() {
    int edad = 30;                  // inicialización con =
    double altura{1.75};            // inicialización con llaves (C++11 en adelante)
    char inicial = 'C';             // comillas SIMPLES: un solo carácter
    bool activo = true;
    std::string nombre = "Camilo";  // comillas DOBLES: cadena de texto

    std::cout << nombre << " (" << inicial << "), " << edad
              << " años, " << altura << " m, activo: " << activo << "\n";
    return 0;
}

Compílalo y ejecútalo (si no tienes claro qué hace cada parte de este comando, la página del compilador lo explica en detalle):

bashbash
g++ -std=c++17 -Wall -o variables variables.cpp
./variables
texttext
Camilo (C), 30 años, 1.75 m, activo: 1

Fíjate en el último dato: bool se imprime como 1 (verdadero) o 0 (falso), no como “true”/“false”. Es la primera de varias sorpresas pequeñas del lenguaje.

Tip

La bandera -Wall activa todas las advertencias comunes del compilador. Úsala siempre desde el primer día: la mayoría de los errores clásicos de C++ (variables sin inicializar, comparaciones sospechosas) aparecen ahí como aviso antes de convertirse en un bug real.

Los tipos fundamentales

Estos son los tipos que trae el lenguaje de fábrica, sin necesidad de ningún #include:

TipoGuardaEjemplo de valorTamaño típico
intNúmeros enteros con signo-7, 0, 424 bytes
doubleNúmeros con decimales3.14, -0.58 bytes
floatDecimales de menor precisión3.14f4 bytes
boolVerdadero o falsotrue, false1 byte
charUn solo carácter'A', '\n'1 byte
unsigned intEnteros sin signo (solo ≥ 0)0, 30000000004 bytes

std::string no está en esta tabla a propósito: no es un tipo fundamental del lenguaje, sino una clase de la Standard Library. Por eso necesita #include <string> y lleva el prefijo std::, tal como se explicó en Namespaces y el prefijo std::.

Advertencia

La columna “tamaño típico” es exactamente eso: típico, no garantizado. El estándar de C++ solo fija tamaños mínimos y relaciones entre tipos; un int puede tener 2, 4 u 8 bytes según la plataforma. Si necesitas un entero de tamaño exacto (formatos de archivo, protocolos de red, registros de hardware), usa los tipos de <cstdint>: int32_t, uint8_t, int64_t. Nunca asumas sizeof(int) == 4 en código que deba ser portable.

auto: que el compilador deduzca el tipo

Desde C++11 puedes escribir auto y dejar que el compilador infiera el tipo a partir del valor inicial:

Ejemplo: deducción de tipo con autocpp
auto contador = 0;        // int
auto precio = 19.99;      // double
auto letra = 'x';         // char

Esto no convierte a C++ en un lenguaje de tipado dinámico: el tipo sigue siendo fijo y decidido en compilación, solo que no lo escribes tú. auto brilla sobre todo con tipos largos de la Standard Library (iteradores, plantillas), donde escribir el tipo completo sería ruido puro.

Nota

Este ejemplo con auto no es representativo del uso real. En código de producción casi nadie escribe auto contador = 0; en lugar de int contador = 0; — con tipos cortos y obvios, escribir el tipo es más legible. auto se usa de verdad cuando el tipo es largo o directamente impronunciable, como std::vector<std::string>::const_iterator.

const: valores que no cambian

Anteponer const marca una variable como de solo lectura: el compilador rechaza cualquier intento de modificarla.

Ejemplo: constante que no se puede modificarcpp
const double PI = 3.14159;
// PI = 3.0;  // ERROR de compilación: assignment of read-only variable 'PI'

Usar const no es una formalidad: le comunica tu intención al compilador y a quien lea el código, y evita modificaciones accidentales. Cobrará mucha más importancia cuando pases datos a funciones por referencia.

Operadores básicos

Aritméticos

OperadorQué haceEjemplo (a = 7, b = 2)Resultado
+Sumaa + b9
-Restaa - b5
*Multiplicacióna * b14
/Divisióna / b3 (!)
%Resto de divisióna % b1
Advertencia

7 / 2 da 3, no 3.5. Cuando ambos operandos son enteros, C++ hace división entera y descarta la parte decimal sin avisar (no redondea: trunca). Para obtener 3.5, al menos uno de los dos debe ser de tipo decimal: 7.0 / 2, o static_cast<double>(a) / b si trabajas con variables. static_cast<double>(a) es una conversión explícita: le pide al compilador “trata este valor como si fuera double”, justo antes de la división, así ya no son dos enteros y no se trunca. Este es probablemente el error silencioso número uno de quien empieza en C++ (y en C, y en Java…).

El operador % solo funciona con enteros, y es más útil de lo que parece: n % 2 == 0 comprueba si un número es par, y aparecerá otra vez en la página de control de flujo.

Comparación y lógicos

Los de comparación devuelven un bool: == (igual), != (distinto), <, >, <=, >=.

Los lógicos combinan condiciones: && (y), || (o), ! (no).

Advertencia

= asigna, == compara. Escribir if (x = 5) compila sin error en muchos casos: asigna 5 a x y la condición resulta verdadera siempre. Con -Wall el compilador te avisa; sin -Wall, no. Es un bug clásico que puede costar horas.

Incremento, decremento y asignación compuesta

  • ++i / i++ suman 1; --i / i-- restan 1.
  • +=, -=, *=, /= combinan operación y asignación: total += 5 es total = total + 5.

La diferencia entre ++i (pre-incremento: incrementa y luego devuelve el valor nuevo) e i++ (post-incremento: devuelve el valor viejo y luego incrementa) solo importa cuando usas el resultado dentro de una expresión más grande. En un bucle suelto, ambos hacen lo mismo. Por cierto, el nombre del lenguaje viene precisamente de este operador: C++ es “C incrementado en uno”.

Ejemplo completo: promedio de dos notas

Este programa junta todo lo anterior con la entrada por consola que ya viste con std::cin:

Ejemplo: calcular el promedio de dos notascpp
#include <iostream>

int main() {
    double nota1 = 0.0;
    double nota2 = 0.0;

    std::cout << "Ingresa la primera nota: ";
    std::cin >> nota1;
    std::cout << "Ingresa la segunda nota: ";
    std::cin >> nota2;

    const double promedio = (nota1 + nota2) / 2.0;   // 2.0, no 2, para evitar división entera

    std::cout << "Promedio: " << promedio << "\n";
    std::cout << "¿Aprobado? " << (promedio >= 4.0) << "\n";
    return 0;
}
bashbash
g++ -std=c++17 -Wall -o promedio promedio.cpp
./promedio
texttext
Ingresa la primera nota: 5.5
Ingresa la segunda nota: 3.5
Promedio: 4.5
¿Aprobado? 1

Fíjate que aquí las variables son double, así que (nota1 + nota2) / 2.0 sí produce decimales. El 2.0 está escrito así deliberadamente: aunque en este caso 2 también funcionaría (porque los operandos ya son double), acostumbrarte a escribir el punto decimal te ahorra la trampa cuando trabajes con enteros.

Advertencia

Una variable declarada sin valor inicial (int x;) no vale 0: contiene basura, es decir, lo que hubiera antes en esa zona de memoria. Leerla es comportamiento indefinido: el programa puede imprimir un número aleatorio, funcionar de casualidad hoy y fallar mañana. Inicializa siempre en la declaración (int x = 0;). Esta misma regla, aplicada a punteros, es la causa de los crashes más comunes de C++, y volveremos a ella en Punteros.

Siguiente paso

Ya sabes guardar y operar valores, pero el programa sigue ejecutándose siempre de arriba a abajo, línea por línea. Para que tome decisiones y repita trabajo, sigue con Control de flujo: if, for, while y switch.