const int *p = &i;
Here p is non-const pointer to const int. As the pointer itself is not const, you can set it to point to something else like NULL, but what it points to is const, so you can't modify it through this pointer.
int * const q = &j;
Here q is const pointer to non-const int. It is initialized to point to j, and you can't change what it points to. But you can change what it points to through it.
const int * const r = &j;
This would be const pointer to const int. So you can't change what it points to, and you can only read the value of what it points to, not change it.