How to Read Complex Variable Declarations? With Qualifiers and Pointers

For example:

const char **p;
char *const *p;
char **const p;

When reading complex variable declarations in C, you can first find the variable name, then read the symbols around it in the order of "near before far, right before left." If you encounter parentheses, the part inside the parentheses takes precedence. For pointers and const, the key is to determine what the const qualifies: when it is to the left of , it usually qualifies the data being pointed to; when it is to the right of , it qualifies the pointer itself.

First look at:

const char **p;

p is a pointer; what it points to is still a pointer; the second-level pointer ultimately points to a const char. In other words, p is a "pointer to a pointer," and the innermost character data cannot be modified through this type. You can read it as: p is a pointer to another pointer, and that second pointer points to a constant character.

Now look at:

char *const *p;

Starting from the variable name p, p first binds to the nearest on the left, so p is a pointer. The content this pointer points to is char const, that is, a "constant pointer." This constant pointer itself cannot be changed to point elsewhere, but the char content it points to is not const, so it can be modified through that pointer.

Therefore, char const p can be read as: p is a pointer to a constant pointer, and that constant pointer points to char.

Finally, look at:

char **const p;

Here, const is to the right of the outermost , so it qualifies the pointer variable p itself. That is, p is a constant pointer and cannot be made to point to another address; what it points to is a char , and that char * in turn points to char.

You can read it as: p is a constant pointer to a char * pointer, and that pointer points to char.

Summary:

const char **p;   // p is a pointer to a pointer; the innermost data is const char
char *const *p;   // p is a pointer to a const pointer; that const pointer points to char
char **const p;   // p itself is a const pointer, pointing to char *

A practical way to judge this is: start from the variable name and read outward. Every time you see a , add one layer of "pointer"; every time you see a const, check which layer it is closest to. If const is close to the type name, such as const char, it qualifies the data; if const is close to the right side of some , such as *const, it qualifies that layer of pointer.

Leave a Reply