Lección 7

Punteros

Respuesta corta: un puntero es una variable que guarda una dirección de memoria. &x te da la dirección de x; *p te da el valor guardado en la dirección que contiene p.

Un puntero es esa dirección

#include <iostream>
using namespace std;

int main() {
    int x = 42;
    int *p = &x;
    cout << "x = " << x << endl;
    cout << "*p = " << *p << endl;
    return 0;
}

p guarda la dirección de x, así que *p lee el mismo 42 a través del puntero. El número de la dirección en sí no se puede imprimir con cout en este motor del navegador — un compilador real lo imprime en hexadecimal.

Guardarla y leer a través de ella

#include <iostream>
using namespace std;

int main() {
    int x = 42;
    int *p = &x;      // p guarda la dirección de x

    cout << *p << endl;   // 42 — lee a través del puntero
    *p = 99;              // escribe a través del puntero
    cout << x << endl;    // 99 — x cambió
    return 0;
}

Ese es todo el mecanismo: p apunta a x, así que escribir a través de p escribe en x. Así es como una función puede cambiar la variable de otra.

Para qué sirve

Para modificar la variable del llamador, pasa su dirección:

#include <iostream>
using namespace std;

void duplicar(int *p) {
    *p = *p * 2;
}

int main() {
    int n = 21;
    duplicar(&n);
    cout << n << endl;   // 42
    return 0;
}

Como el argumento es una dirección, la función cambia la n del llamador. Pasarla por valor solo cambiaría una copia. Comparación completa de las tres formas: valor, puntero, referencia.

Arrays y punteros son primos

#include <iostream>
using namespace std;

int main() {
    int a[3] = {10, 20, 30};
    int *p = a;          // el nombre del array decae a la dirección del primer elemento

    cout << *p << endl;       // 10
    cout << *(p + 1) << endl; // 20 — la aritmética avanza por elementos
    return 0;
}

Por eso los arrays se pasan "por referencia" sin que hagas nada: lo que se pasa es la dirección del primer elemento.

Las dos reglas

Los punteros son la razón de la fama de C++. En C++ moderno la mayoría de los punteros crudos se sustituyen por referencias y punteros inteligentes — mira la ruta de C++ moderno.

Practica esta lección

Estos problemas ejercitan exactamente lo que acabas de leer: