Lección 1 · 1 de 20
Punteros a punteros y aritmética · C
Recorra arrays en C con aritmética de punteros, reste punteros y use un puntero a puntero para que una función cambie a dónde apunta otro.

La aritmética de punteros cuenta en elementos, no en bytes: si p apunta a prices[0], p + 2 apunta a prices[2] y *(p + 2) es lo mismo que prices[2]. El compilador multiplica por el tamaño del tipo, y por eso (char *)(p + 1) - (char *)p da 8, los bytes de un double.
Restar dos punteros del mismo array da cuántos elementos hay entre ellos, con el tipo ptrdiff_t (se escribe con %td). (prices + n) - p es 5, y cheapest - prices convierte un puntero en su índice. Apuntar una posición después del último elemento, como prices + n, está permitido para comparar, pero no para leer *.
Una función recibe copias de sus argumentos. Para que find_cheapest cambie el puntero cheapest de main, se le pasa su dirección, &cheapest, y el parámetro es un puntero a puntero, double **. Dentro, *cheapest es el puntero de main y **cheapest es el precio al que apunta.
El caso más habitual de ** es una lista de cadenas: shops es un array de const char * que termina en NULL, como argv. const char **s recorre la lista: *s es cada cadena y **s, su primera letra.
En DMarlon Studio, este programa se escribe en el destino Consola y se compila y ejecuta con un clic (F9).
Código · main.c
#include <stdio.h>#include <string.h>// Receives the address of a pointer and makes it point at the cheapest price.void find_cheapest(double *prices, int n, double **cheapest) { *cheapest = prices; for (double *p = prices + 1; p < prices + n; p++) if (*p < **cheapest) *cheapest = p;}int main(void) { double prices[] = {4.50, 3.20, 5.10, 2.95, 3.80}; int n = sizeof prices / sizeof prices[0]; // Pointer arithmetic: p + 2 moves two elements, not two bytes. double *p = prices; printf("First: %.2f, third: %.2f\n", *p, *(p + 2)); printf("Bytes from p to p + 1: %td\n", (char *)(p + 1) - (char *)p); printf("Elements from start to end: %td\n", (prices + n) - p); double *cheapest = NULL; find_cheapest(prices, n, &cheapest); printf("Cheapest: %.2f at index %td\n", *cheapest, cheapest - prices); // A list of strings is an array of pointers: char ** walks through it. const char *shops[] = {"Bakery", "Market", "Kiosk", NULL}; for (const char **s = shops; *s != NULL; s++) printf("Shop %td: %-7s first letter %c, %zu letters\n", s - shops, *s, **s, strlen(*s)); const char **second = shops + 1; printf("Through **: %s starts with %c\n", *second, **second); return 0;}Salida · cc main.c -o main && ./main
First: 4.50, third: 5.10 Bytes from p to p + 1: 8 Elements from start to end: 5 Cheapest: 2.95 at index 3 Shop 0: Bakery first letter B, 6 letters Shop 1: Market first letter M, 6 letters Shop 2: Kiosk first letter K, 5 letters Through **: Market starts with M
Para recordar
p + iavanzaielementos;*(p + i)esp[i].- La resta de punteros da elementos, con
%td. - Para cambiar un puntero desde una función, pase
&punteroy recibaT **. - Un array de cadenas se recorre con
char **hastaNULL.
Ejercicio
Escriba find_dearest con la misma forma que find_cheapest y use las dos para escribir el precio más alto, el más bajo y la distancia en elementos entre ellos.