Lección 15 · 15 de 20
Punteros: dirección y valor · C
Aprenda qué es un puntero en C: la dirección de una variable con &, el valor con *, funciones que cambian variables ajenas y NULL.

Cada variable ocupa un lugar en la memoria con una dirección. El operador `&` da esa dirección y un puntero es una variable que la guarda: int *p = &score; declara p como «puntero a int» y lo hace apuntar a score. La dirección cambia de una ejecución a otra, por eso el ejemplo solo comprueba que p == &score.
El operador ***** delante de un puntero va a esa dirección: *p es el valor de score, 50. Y también sirve para cambiarlo: tras *p = 75, score vale 75, porque p y score se refieren al mismo sitio.
Aquí está la gran utilidad de los punteros. En la lección 13 vio que una función recibe copias; si en cambio recibe una dirección, puede cambiar la variable original. add_points(&score, 25) suma 25 a score, y swap intercambia gold y silver. Es lo que hace scanf con el &age de la lección 5.
`NULL` es un puntero que no apunta a nada. Antes de usar con * un puntero que podría ser NULL, compruébelo: leer *nowhere haría que el programa fallara.
Código · main.c
#include <stdio.h>// With a pointer, a function can change the caller's variable.void add_points(int *score, int points) { *score += points;}void swap(int *a, int *b) { int tmp = *a; *a = *b; *b = tmp;}int main(void) { int score = 50; int *p = &score; // & gives the address; p stores it // The address changes from run to run, so we only compare it. printf("p points to score: %s\n", p == &score ? "yes" : "no"); printf("score = %d, *p = %d\n", score, *p); *p = 75; // * follows the address and changes the value there printf("after *p = 75, score = %d\n", score); add_points(&score, 25); printf("after add_points, score = %d\n", score); int gold = 3, silver = 8; swap(&gold, &silver); printf("after swap: gold = %d, silver = %d\n", gold, silver); int *nowhere = NULL; // NULL: points to nothing, check before use if (nowhere == NULL) printf("nowhere is NULL\n"); return 0;}Salida · cc main.c -o main && ./main
p points to score: yes score = 50, *p = 50 after *p = 75, score = 75 after add_points, score = 100 after swap: gold = 8, silver = 3 nowhere is NULL
Para recordar
&xda la dirección dex.int *pes un puntero aint.*plee o cambia el valor al que apunta.- Con un puntero, una función puede cambiar las variables de quien la llama.
- Compruebe que un puntero no es
NULLantes de usarlo.
Ejercicio
Escriba void split_bill(double total, int people, double *each, double *tip) que guarde lo que paga cada persona y una propina del 10 %, y escriba ambos valores desde main.