A pointer is an unsigned short or unsigned long whose value is the address of a place in memory of a particular data type. Two pointers may contain the same address yet not be
f the same type because a pointer is more than just the address it contains. That address must be the start of a place in memory of a certain size and that place in memory must have specific properties. That is, this value must be the address of a variable of a particular data type. This data type may be called the base type of the pointer.
It may seem reasonable that there should be a pointer data type since pointers are just an unsigned short or an unsigned long. However there is more to this relationship than just the address the pointer contains. It is also the size of the memory being pointed to and the properties of that memory.
It is possible to specify the address of any place in memory by using the address operator & on the variable which names that place in memory. For example:
stuffType Stuff; cout << "The address of stuff is " << &Stuff;
will display the address of the variable stuff on the screen. See ADDRESES.CPP which shows the address of several variables of different data types using the address operator.
Before a variable may be a pointer, it must be defined. The pointer definition operator * is used to define a pointer. This operator is read: "is a pointer to an instance of type". For example:
defines ptrStuff to be a pointer to an instance of type stuffType
To reference an instance of a data type, the pointer must be initialized. This is done in the following manner:
ptrStuff = &Stuff;
which is read:
ptrStuff "is assigned the address of" Stuff
or we could have written this as follows:
stuffType *ptrStuff = &Stuff;
where the pointer may be defined and initialized in the same statement. See PTRINTLIZ.CPP.
It is possible to use a pointer to access the memory to which the pointer addresses by using the indirection operator: * For example:
int anInt; int * ptrInt = &anInt; *ptrInt = 5;
the last statement assigns an int value (also called a literal) 5 to anInt. See INDIRECT.CPP. Notice that the symbol * is used for several different operations. You must be careful when you code to keep these differences separate.
When more that one pointer of a particular type is to be defined at the same time, one must be careful how they are defined. For example in the following definition:
int *ptrint1, ptrint2;
ptrint2 is not a pointer but an int variable instead. If two pointers of the same type are to be defined in the same statement, it is necessary to define them as in the following:
int *ptrint1, *ptrint2;
The location of the pointer definition operator depends on choice not syntax. Any of the following are syntactically correct:
char* ptrChr; int * ptrInt; float *ptrFloat;
The first of these is the preferred location. This preferred position is especially true when used with functions. (A pointer as an unsigned int or an unsigned long may be used as input or output to a function.) For example:
int f(char* );
Notice how the pointer definition operator is used in the above prototype. Notice how the operator is used when the output is a pointer as in the following function prototype:
double * g(int);
Suppose ptr is a pointer of base type: type1 and var is a variable of data type: type2. In general the following assignment should cause a compiler error:
type1 * ptr; type2 var; ptr = &var; // syntax error will occur because of this statement
However, under certain circumstances, it is possible to store the address of a variable of one data type into a pointer of an entirely different data type by using type casting as in the following example: (but be very careful about doing this because this can introduce memory errors):
ptr = (type1*) &var;
See pointerconversion.cpp.This type of conversion is used when certain functions are used for file I/O.