Problem: an object that holds a pointer value need not be a variable. For
example:
int i = 6;
int * const p = &i; /* p is not a variable - or at least, to persuade anyone
that it is, you'd have to have kissed the Blarney. */
I suppose that depends on the definition of the word variable. Perhaps
this is why the C standard doesn't say much about "variables".
In any case, I would call p a variable - a const variable. If you're
speaking English, it's a contradiction, but we're speaking jargon.
This seems an opportune place to insert the rewritten first paragraphs
of my earlier post to Alan, the woefully misinformed. Comments are
welcome:
-------------------------------------
C Pointer Basics
Objects:
The C Standard defines an object as "a region of storage", that is, some
contiguous sequence of bytes in computer memory. An object has a size and
can store values. Objects also have a lifetime. An object can be created
and exist, and then later be destroyed and no longer exist.
Variables:
Variables can be thought of as named, typed, objects. A variable is declared
with a name and a type. Variables are also associated with some amount of
memory. That region of memory is an object -- the object named by the
variable.
Pointers:
A pointer is a kind of value that can "point to" some object. Most of the
pointers in a C program are usually values stored in pointer variables, that
is, a variable that has been declared with a pointer type.
There are also pointer values that are not stored in variables, and a special
kind of pointer called a null pointer, that, although it is a pointer does
not point to any object at all.
Pointers can be valid or invalid. A valid pointer has a value that points to
an existing object. An invalid pointer has a value that does not point to an
existing object. If a pointer is valid, and points to an existing object, and
the object is then destroyed, the pointer becomes invalid, for the object to
which it pointed no longer exists.
You might wonder what it means for a pointer to "point to" an object. It
means that it is possible to access the object by using the pointer to see
where it is.
For example, let an integer variable be declared in a C program:
int main (void)
{
int x; /* x: a variable of type int */
...
return 0;
}
The declaration causes the name x to become associated with a region of
memory. The region of memory is the object associated with the variable x.
x is also associated with a type, in this case the type of x is int. C
allows us to set and retrieve the value of the object named x:
#include <stdio.h>
int main (void)
{
int x; /* x: a variable of type int whose value is undefined */
x = 3; /* set the value stored in the object named x to 3 */
printf("x == %d\n", x); /* print the value of the object named x */
return 0;
}
This program will produce the output
x == 3
You might wonder why the comment in the sample code above verbosely reads
"set the value stored in the object named x to 3" instead of "set x to 3".
Although it is common for C programmers to abbreviate and say things like
"set x to 3", the comment above is written as it is because it is possible
to manipulate the object associated with x without actually using the name
x. It is important to understand that what is being changed is the value
stored in an object. Although x could be considered the "main" or "canonical"
name of the object, it can be referred to in other ways as well, and its
value can be set and retrieved using those other ways.
One other way of referring to the object named x is to use a pointer:
int main (void)
{
int x; /* x: a variable of type int */
int *p /* p: a variable of type pointer to int */
p = &x; /* make p point to the object named x */
...
return 0;
}
Now p is the name of a pointer that refers to the same object as x and we
can manipulate the value of the object named x by accessing that object
"through" the pointer named p.
#include <stdio.h>
int main (void)
{
int x; /* x: a variable of type int */
int *p /* p: a variable of type pointer to int */
p = &x; /* make p point to the object named x */
*p = 5; /* set the value of the object pointed to by p to 5 */
/* the object pointed to by p is the same as the object
named x. */
printf("x == %d\n", x);
printf("*p == %d\n", *p);
return 0;
}
This program will produce the output
x == 5
*p == 5
The value stored in the object named x has been altered by using p. The
object that p points to is the same as the object that is named x. This can
be said more succinctly "p points to x". However, p is not the same as x.
p is also the name of an object. That object has a type (pointer to int),
and a value of some kind. The value of p "refers to" the object named x, but
how it does that is of no concern to C programmers, all that is important is
that we can manipulate that value in certain ways.
To try to make this clear before talking more about the value of p, here's
a diagram that attempts to show the objects named p and x in memory
+-----------+
| (value)--+------+
+-----------+ | +-----------+
p: pointer to int +----->| 5 |
+-----------+
x: int
There is an object named p, and an object named x. The object named x has the
value 5 and the object named p has a value that points to x.
------------------------------------------