DMarlon Studio

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.

C · Punteros: dirección y valor en DMarlon Studio: el código del ejemplo y su salida en la terminal

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

  • &x da la dirección de x.
  • int *p es un puntero a int.
  • *p lee 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 NULL antes 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.