C Language provides for types "pointer to T", for a type T, whose values are used to access locations storing type T values. Pointer values can be thought of as memory addresses, and often associated with a long integer, the byte number where the location starts in memory.
Every variable has two values associated with it: the rvalue of the value stored at the location, and the lvalue which is the address of the location. Lvalues exist in the type space of "pointer to T", where T is the type stored at the location.
Pointers are declared as a recapitulation of how they are used. If p is of type pointer to int, then "* p" is type int. Therefore, clear p as "int * p". In general, if p is type "pointer to T", then *p is type T. The following is type correct for pointers to pointers:
int i ; int * p ; int ** pp ; p = *pp ; i = *p ;
If t names a location for type T, then &t is the lvalue of t, and is of type pointer to T. The value of &t allows access to the location of t:
int t ; int * p ; p = &t ; *p = 1 ; /* this stores 1 in t */ assert( t==1 ) ;the assertion is always true.
Consider carefully the assignment *p = 1
. As an lvalue a variable
must match the type of the value being placed into the location.
1 is of type int, so *p must be used, since p is type pointer to int, not int.