Constant pointer, Pointer to Constant and constant pointer to constant
Types of Pointer in C language

A pointer that constantly points to the same address of its type throughout the program is known as a constant pointer, whereas a pointer that points to a constant (the value at that address can't be changed by this pointer) is termed a pointer to constant.

Let's understand it by an example, but first check out the prerequisite posts on Pointers in C, Double pointer in C, and Pointer vs Reference variable in C/C++.

Constant Pointer

As the name implies, a constant pointer constantly points to a fixed memory address of its type. It can't be re-assigned or modified to another address. In case the developer wants to do so, the compiler will raise an illegal operation error — but the value at that pointed address can be modified.

//Syntax
<type of pointer> *const <name of pointer>;

#include <stdio.h>
    int main(void) {
    //Declaration
    int a = 10;          //Variable
    int * const b = &a;  // Constant pointer

    //Re-assigning
    int c=15;       //Another variable
    b = & c;   // Error, because constant pointer can't be modified
    return 0;
}
prog.c: In function 'main':
prog.c:11:3: error: assignment of read-only variable 'b'
b = & c;

Pointer to constant

A pointer that constantly points to a fixed value at the memory address. We can't modify that value using this pointer, but we definitely can modify or re-assign the pointer to another address.

//Syntax
const <type of pointer>  * <name of pointer>;
or
<type of pointer>  const * <name of pointer>;

#include <stdio.h>
int main(void) {
      //Declaration
      int a = 10;          //Variable
      const int * b = &a; // Pointer to constant

//Re-assigning
      int c=15;     //Another variable
     b = & c;      //Re-assigned — allowed
    *b = 25; // Error — value modification not allowed using pointer to constant
  return 0;
}
Compilation error
prog.c: In function 'main':
prog.c:10:6: error: assignment of read-only location '*b'
   *b = 25;

Constant Pointer to constant

A pointer that neither can be modified or re-assigned, nor the pointed value can be modified, is termed as a constant pointer to constant.

//Syntax
const <type of pointer>  *  const <name of pointer>;

#include <stdio.h>
int main(void) {
      //Declaration
      int a = 10;       //Variable
      const int * const b = &a; // constant Pointer to constant

//Re-assigning
      int c=15;   //Another variable
     b = & c;    //Error — Re-assign not allowed
    *b = 25;     // Error — value modification not allowed
  return 0;
}
prog.c: In function 'main':
prog.c:10:8: error: assignment of read-only variable 'b'
      b = & c;
        ^
prog.c:11:8: error: assignment of read-only location '*b'
     *b = 25;

Applications of Different kinds of pointers

When you're designing C programs for embedded systems, or special purpose programs that need to refer to the same memory (multi-processor applications sharing memory) then you need constant pointers.

Pointer to constant is commonly used while passing a pointer as a parameter where value modification is not allowed or value is read-only.
Constant pointer to constant is used, for example, for knowing the status of a specific interrupt through the pointer.