Pointer to Constant vs Constant Pointer in C

In the C programming language, the distinction between a pointer to a constant and a constant pointer determines what can and cannot be modified in memory. A pointer to a constant prevents modification of the underlying data through that pointer, while allowing the pointer itself to point to a different memory address. Conversely, a constant pointer is fixed to a specific memory address that cannot be changed once initialized, though the data residing at that address can be modified. Understanding this semantic difference is crucial for writing safe, bug-resistant C code.

The Rule for Reading Pointer Declarations

To decipher pointer declarations in C, read them backwards from right to left, starting with the identifier. This technique clearly reveals whether the pointer itself or the pointed-to value is constant:

  • const int *ptr; — Read right-to-left: ptr is a pointer to an integer that is constant.
  • int *const ptr; — Read right-to-left: ptr is a constant pointer to an integer.

Pointer to a Constant

A pointer to a constant treats the target memory as read-only through this specific pointer, even if the underlying variable was not initially declared as a constant.

Syntax

const int *ptr;
// or equivalent:
int const *ptr;

Behavior

  • Target Value: Read-only via dereferencing (*ptr = 20; produces a compiler error).
  • Pointer Address: Mutable (ptr = &another_var; is completely valid).
int x = 10;
int y = 20;
const int *ptr = &x;

// *ptr = 15;  // Error: assignment of read-only location
ptr = &y;      // Allowed: the pointer can point to another address

Typical Use Case

This pattern is widely used in function parameters to pass large data structures by reference without copying, while guaranteeing the function will not inadvertently modify the original caller data (e.g., standard library functions like strlen(const char *s)).

Constant Pointer

A constant pointer is a pointer whose stored memory address cannot be altered after initialization. It must be initialized at the time of declaration.

Syntax

int *const ptr = &variable;

Behavior

  • Target Value: Mutable via dereferencing (*ptr = 20; is completely valid).
  • Pointer Address: Read-only (ptr = &another_var; produces a compiler error).
int x = 10;
int y = 20;
int *const ptr = &x;

*ptr = 15;     // Allowed: the underlying value can be modified
// ptr = &y;   // Error: assignment of read-only variable

Typical Use Case

Constant pointers are frequently used in embedded systems programming to represent fixed hardware registers or memory-mapped I/O addresses, ensuring that the software cannot accidentally redirect the pointer to another location in memory.

Constant Pointer to a Constant

Both concepts can be combined to lock down both the memory address and the data:

const int *const ptr = &x;

In this case:

  • You cannot change the address stored in ptr.
  • You cannot change the value of x through ptr.

Summary of Semantic Differences

Type Syntax Can Modify Value? Can Change Address?
Pointer to Constant const int *ptr No Yes
Constant Pointer int *const ptr Yes No
Const Pointer to Const const int *const ptr No No