Lección 5 · 5 de 20
const y punteros · C
Distinga en C entre puntero a const, puntero const y los dos a la vez, y use const en los parámetros para prometer que una función solo lee.

`const` hace que el compilador impida escribir en algo. Con punteros hay dos cosas que se pueden proteger: los datos a los que apunta y el propio puntero. La regla para leerlo: const afecta a lo que tiene a su izquierda o, si no hay nada, a lo de su derecha.
const char *shop es un puntero a const: no se puede escribir *shop = 'x', pero shop sí puede apuntar a otra cadena. Es el tipo correcto para las cadenas literales y para casi cualquier parámetro de texto, como el de count_upper, que mueve s por la cadena sin cambiarla.
char *const first = city es un puntero const: siempre apunta a city, pero a través de él sí se escribe, y first[0] = 'M' pone la mayúscula a Madrid. const double *const rate protege las dos cosas.
En los parámetros, const es una promesa a quien llama. show(const Book *b) solo lee el libro: si dentro se intentara b->stock = 0, el programa no compilaría. sell(Book *b, …) no lleva const porque cambia el stock, y eso se ve ya en su declaración.
Las líneas comentadas del ejemplo son errores de compilación a propósito: quite el // de una de ellas para ver el mensaje del compilador.
Código · main.c
#include <ctype.h>#include <stdio.h>typedef struct { const char *title; double price; int stock; } Book;// const Book *: the function promises to only read the book.void show(const Book *b) { printf("%-15s %6.2f stock %2d\n", b->title, b->price, b->stock); // b->stock = 0; // error: assignment to a read-only location}void sell(Book *b, int units) { b->stock -= units; } // Book *: may change itint count_upper(const char *s) { int n = 0; for (; *s; s++) // s itself moves; what it points to is read-only if (isupper((unsigned char)*s)) n++; return n;}int main(void) { Book book = {"The C Language", 39.90, 12}; show(&book); sell(&book, 3); show(&book); char city[] = "madrid"; const char *shop = "Libros DMarlon"; // pointer to const: can move, can't write char *const first = city; // const pointer: can write, can't move first[0] = 'M'; // first = shop; would not compile const double vat = 0.04; const double *const rate = &vat; // neither the pointer nor the value printf("%s (%d capitals) in %s, VAT %.0f%%\n", shop, count_upper(shop), city, *rate * 100); return 0;}Salida · cc main.c -o main && ./main
The C Language 39.90 stock 12 The C Language 39.90 stock 9 Libros DMarlon (3 capitals) in Madrid, VAT 4%
Para recordar
const T *p: no se escribe en*p;ppuede moverse.T *const p:pno se mueve;*pse puede escribir.const T *const p: ninguna de las dos cosas.- Ponga
consten los parámetros que la función solo lee.
Ejercicio
Escriba double stock_value(const Book *books, int n) que sume precio por stock de un array de libros, y compruebe que el compilador protesta si dentro intenta cambiar un precio.