The author is saying that the C implementation must reserve one of the addresses that the processor can use, so that in C that address is used to represent a null pointer. Hence, C can address one fewer memory locations than the processor can. Convention is to use address 0 for null pointers.
In practice, a 32-bit processor can't really address 2^32 memory locations anyway, since various parts of the address space will be reserved for special purposes rather than mapped to memory.
There's also no actual requirement that the C implementation represent pointers using the same sized addresses that the processor uses. It might be horribly inefficient to do so, but the C implementation could use 33-bit pointers (which would therefore require at least 5 bytes of storage, and wouldn't fit in a CPU register), enabling it to use a value for null pointers that isn't one of the 2^32 addresses the processor can handle.
But assuming nothing like that, it's true that a 32 bit pointer can represent any of 2^32 addresses (whether those addresses refer to memory locations is another matter), and it's also true that since C requires a null pointer, one of those addresses must be used to mean "a null pointer".