The first two are the same and means a pointer to const char. The second is a constant pointer to (non-const) char. In the first case, you can/could change the pointer, not but what it points at. In the second case, you can change what it points at, but not make the pointer refer to different memory.
The main thing with pointer declarations/definitions is to keep track of the '*':
char X * Y ptr;
Either 'X' or 'Y' can be replaced by const
, or volatile
, or both. The 'X' replacement will modify what the pointer points AT. The 'Y' replacement will modify the pointer itself. On the 'X' part, you can have X char
or char X
-- this makes no difference at all. What makes a difference is placement relatively to the '*'. If the modifier is next to the name of the type, it modifies what the pointer points at. If the modifier is next to the name of the pointer, then it modifies the pointer itself.