The type qualifiers may modify type names and derived types. Derived types are those parts of declarations in C that can be applied repeatedly to build more and more complex types: pointers, arrays, functions, structures, and unions. Except for functions, one or both type qualifiers can be used to change the behavior of a derived type.
The following example declares and initializes an object with type const int whose value is not changed by a correct program.
const int five = 5;
The order of the keywords is not significant to C. For example, the following declarations are identical to the first example in its effect:
int const five = 5;
const five = 5;
The following declaration declares an object with type pointer to const int, which initially points to the previously declared object.
const int *pci = &five;
The pointer itself does not have a qualified type, but rather it points to a qualified type. It can be changed to point to essentially any int during program execution. pci cannot be used to modify the object to which it points unless a cast is used, as in the following example:
*(int *)pci = 17;
If pci actually points to a const object, the behavior of this code is undefined.
The following declaration indicates that somewhere in the program is a definition of a global object with type const pointer to int.
extern int *const cpi;
In this case, cpi’s value will not be changed by a correct program, but it can be used to modify the object to which it points. Notice that const comes after the * in the declaration. The following pair of declarations produces the same effect:
typedef int *INT_PTR; extern const INT_PTR cpi;
These declarations can be combined as in the following declaration in which an object is declared to have type const pointer to const int :
const int *const cpci;