jagguy posted:
can you declare variables as pointers without using new or make them
point at another variable.
In C++, we have loads of different primitive, built-in types. Here's a few:
int
unsigned
char
bool
float
double
When you define a variable, you choose its type depending on what kind of
data you want to store in it. If you want to store a character, it makes
sense to use a "char". If you want to store a negative integer, it makes
sense to use an "int".
There are times when you want to store a memory address. C++ has very
advanced, built-in functionality for storing and working with memory
addresses. You don't just use a integer variable:
unsigned int memory_address = 29237689;
Instead, you use something called a pointer variable. Before you define a
pointer variable for storing a memory address though, you have to choose
what actually exists at the memory address in question. Let's say that
there's an "int" stored at memory address 2470706. If we want to store this
int's memory address in a variable, it makes sense to use an "int pointer".
Let's define a variable for storing the address of an "int".
int *p;
When you define a variable within a function in C++, it doesn't have any
definite value unless you give it one. In the previous example, "p" could
contain ANY memory address, so it would be unwise to mess around with it.
If we're going to use this pointer variable properly, it makes sense to
store a legitimate address in it, i.e. the address of an actual "int". Here
would be the most simple way:
int k = 5;
p = &k;
The ampersand above gives us the address of the variable "k".
We can now use the asterisk operator on "p" to make it act like we're
dealing with "k" itself:
*p = 23;
Now let's store a different address in "p":
int f = 2;
p = &f;
And let's use the dereference operator (i.e. the asterisk) to work with the
"pointed to" object:
*p = 16;
The "new" operator returns the address of the object which it has created.
We can store this address in "p":
p = new int;
And we can use the dereference operator to access the object:
*p = 88;
The "delete" operator wants to be supplied with a memory address also:
delete p;
Now we can use "p" for something else again:
int g = 3;
p = &g;
And use the dereference operator to access the object:
*p = 45;
One thing you'll notice about pointers is that you can't do the following:
p = 25262726;
(Here, we're trying to store the memory address 25262726 in the variable
"p").
C++ knows that there's not much reason why you'd have a "raw" memory
address hardcoded like that, so it refuses to compile the code. However,
being the hardcore language that C++ is, you can be forceful about your
intentions:
p = reinterpret_cast<int*>(25262726);
Here, we're twisting the compiler's arm and telling it to treat 25262726 as
if it was the address of an "int", i.e. an "int*".
There is one integer value however which the compiler will passively let
you store in "p", and that value is zero:
p = 0;
This is called the "null pointer value". We use it to indicate that "p"
doesn't point to anything (i.e. that it doesn't contain a valid memory
address). This can be useful in code:
if ( !p ) DontDoSomething();
/* If "p" doesn't point to something, the don't
do anything */
Another fancy thing about pointer variables is "pointer arithmetic". To
demonstrate this functionality, first I'm going to have to define an array:
int array[10];
Let's store the address of the 1st element in an "int pointer" variable:
int *p = *array;
(Here, "array" written on its own has decayed from being an array, to being
a pointer to the 1st element of the array. The dereference operator then
gives us the 1se element itself)
When we define an array, we're guaranteed that each element is DIRECTLY
after the other in memory.
The address of the first element of the array is stored in "p". Let's say
we want "p" to point to the 2nd element of the array. For this example,
we'll assume that an "int" consists of four bytes. Therefore it would make
sense to add four bytes to the address which is already stored in "p",
i.e.:
p = p + 4;
or better written as:
p += 4;
However, being the fancy, advanced thingies that pointers are, they've
already taken this into account. All you have to do is add one to it, and
the compiler deals with figuring out how big an "int" is. So all you write
is:
p = p + 1;
or better written as:
p += 1;
which is even better written as:
++p;
That's the essence of pointer arithmetic.
If I have a pointer to a double, e.g.:
double array[7];
double *p = *array;
and if I want to point to the next element, all I have to do is:
++p;
(I don't have to consider that a "double" may be eight bytes long on this
particular system).
If you want to learn more about pointers and arrays, a recent post of mine
may be helpful:
http://groups.google.ie/group/comp.lang.c/msg/32b330cdf8aba3d6?hl=en&
-Tomás