A pointer is a data type which holds a memory address. A pointer can be
thought of as a reference to that memory address, while a variable
accesses that memory address directly. If a variable is someone's phone
number, then a pointer is the page and line number where it's listed in
the phone book. To access the data stored at that memory address, you
dereference the pointer.
To declare a pointer data type, you must specify what it will point
to. That data type is preceded with a carat (^). For example, if you are
creating a pointer to an integer, you would use this code:
type
PointerType = ^integer;
|
You can then, of course, declare variables to be of type PointerType.
Before accessing a pointer, you block off an area in memory for that
pointer to access. This is done with:
To access the data at the pointer's memory location, you add a carat
after the variable name. For example, if PointerVariable was
declared as type PointerType (from above), you can assign
the memory location a value by using:
After you are done with the pointer, you must deallocate the memory
space. Otherwise, each time the program is run, it will allocate more and
more memory until your computer has no more. To deallocate the memory, you
use the Dispose command:
Dispose(PointerVariable);
A pointer can be assigned to another pointer. However, note that since
only the address, not the value, is being copied, once you
modify the data located at one pointer, the other pointer, when
dereferenced, also yields modified data. Also, if you free (or deallocate) a
pointer, the copied pointer now points to meaningless data.
What is a pointer good for? Why can't you just use an integer in the
examples above instead of a pointer to an integer? Well, the above is
clearly a contrived example. The real power of pointers is that, in
conjunction with records, it makes dynamically-sized data structures
possible. If you need to store many items of one data type in order, you can
use an array. However, your array has a predefined size. If you don't have a
large enough size, you may not be able to accomodate all the data. If you
have a huge array, you take up a lot of memory when sometimes that memory is
not being used.
A dynamic data structure, on the other hand, takes up only as much memory
as is being used. What you do is to create a data type that points to a
record. Then, the record has that pointer type as one of its fields. For
example, stacks and queues can all be implemented using this data structure:
type
PointerType =
^RecordType;
RecordType =
record
data : integer;
next :
PointerType;
end;
|
Each element points to the next. The last record in the chain indicates
that there is no next record by setting its next field to a value
of nil.