Lesson 5 · 5 of 20
const and pointers · C
Tell apart a pointer to const, a const pointer and both at once in C, and use const parameters to promise that a function only reads.

`const` makes the compiler refuse writes to something. With pointers there are two things you can protect: the data it points at and the pointer itself. The reading rule: const applies to what is on its left or, if there is nothing there, to what is on its right.
const char *shop is a pointer to const: you cannot write *shop = 'x', but shop can point to another string. It is the right type for string literals and for almost every text parameter, like the one in count_upper, which moves s along the string without changing it.
char *const first = city is a const pointer: it always points at city, but you can write through it, and first[0] = 'M' capitalises Madrid. const double *const rate protects both things.
On parameters, const is a promise to the caller. show(const Book *b) only reads the book: trying b->stock = 0 inside would not compile. sell(Book *b, …) has no const because it changes the stock, and you can tell from its declaration alone.
The commented-out lines in the example are deliberate compile errors: remove the // from one of them to see the compiler's message.
Code · 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;}Output · 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%
Key points
const T *p: no writes to*p;pcan move.T *const p:pcannot move;*pcan be written.const T *const p: neither.- Mark the parameters a function only reads as
const.
Exercise
Write double stock_value(const Book *books, int n) that adds up price times stock over an array of books, and check that the compiler complains if you try to change a price inside it.