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
- Nunca desreferencies un puntero sin inicializar.
int *p; *p = 5;escribe en una dirección aleatoria. Apúntalo a algo primero, o ponlo anullptr. - Nunca uses un puntero a algo que ya no existe. Un puntero a una variable local fuera de ámbito está colgando — esa memoria puede estar reutilizada.
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: