Next: Dynamic Allocation of Up: Introduction to C++ Previous: Enumeration Types

Pointers and Arrays

We will give an extended introduction to this topic, more than you really need to understand the examples in this document. That is because pointers are one of the most important concepts in C/C++ , and the introductions we have read were rather opaque.

One of the powerful features of C/C++ that is lacking in FORTRAN is pointers. Pointers are extremely powerful. Pointers seem very strange at first and the advantages may not be immediately obvious. However, most new C programmers soon regard them as one of their favorite features. We will explain them and show you some examples here.

In FORTRAN we have only data types such as INTEGER, REAL etc. In C/C++ we have another type of variable known as a pointer. A pointer is a variable which contains a memory address of a particular type of variable. So, in other words, an integer pointer is a pointer to an address in memory which contains an integer value.

In declarations we use a * in front of a variable name to indicate that the variable is a pointer. So, let's look at some examples:


int i;          //declare a Normal integer
int *p;         //declare a pointer called p. p will point at an integer
erp *erpBox;    //declare a pointer called erpBox. erpBox will point at an erp

You might ask ``What is the actual value of a pointer, what would I see if I printed it to the screen?''. Well, the value of a pointer is the actual address in memory that it points to. So when we initialize a pointer to some value what we actually do is set it equal to an address of a variable of some sort.

Because of this, you can see that we need a way to be able to get the address in memory of a variable. We do this by use of the &operator. The &placed in front of a variable means ``the address of''. So let's look at how we can make the pointer p that we created in our example point at an integer.


int *p;        //declare a pointer called p. p will point at an integer
int myVar;     //Make an integer variable called myVar
myVar=6;       //set myVar = 6
p = &myVar;    //make p contain at the address of myVar

In this example we created both an integer variable (myVar) and an integer pointer (p). After we initialize myVar to 6 we initialize the pointer to the address of myVar (the integer variable). Remember that pointers contain addresses of locations in memory.

At this point, we should mention that there is a special address called NULL (in fact it is equal to zero). The compiler guarantees that it will never put any real data at address NULL. We may set a pointer equal to NULL by saying p = NULL. A subroutine may do this to indicate that it could not find anything useful to make p point at. Later code may test whether p is non-null:


  p = getPtr();
  if (p != NULL) usePtr(p);

Now what if we want to actually refer to the contents of what a pointer points at. After all there is no use of pointing at something if we can't access it! We also use the * to mean ``the contents of this address in memory'' if we put it in front of a pointer variable. So, if we want to look at what p points at (in this case the integer 6) we can type:


int NewVar;    //Make a new integer variable
newVar = *p;   //Make a newVar = to what p points at (in this case 6)

Now NewVar contains the value of what p points at (in this case 6). Now recall the line:


erp *erpBox

from our previous example. In this line, erpBox is a pointer to a class variable (a variable of the erp class which we defined before). When we discussed classes in the FARFALLA User Guide, we showed how to access the data members. If erpBox was a variable of type erp we typed erpBox.adc0u. But what do we do if erpBox is a pointer to an erp? Well there are two ways to do this. First we will show you the way it is usually not done.


(*erpBox).adc0u

You can see what is happening here. The (*erpBox) means what the erpBox pointer points to (in this case an erp). The parentheses are necessary to denote what the * refers to. What we usually write instead however uses this special notation:


erpBox->adc0u

Here the ``'' symbol is a minus sign followed by a greater-than sign. We read this ``erpBox pointing at adc0u''. So the arrow means ``pointing at''. So here is an example we gave before but this time with pointers:



erp myErpBox            //Make an erp variable called myErpBox
erp *erpBox;            //Make a erp pointer called erpBox
erpBox = &myErpBox      //Have erpBox point at the contents of myErpBox

erpBox->adc0u =  6;     //Set adc0u = 6
erpBox->energy = 10.0;  //Set the energy to 10 Mev.

int energy;             //make an Integer variable called energy;
energy = erpBox->energy;//Set energy = 10 Mev(the value of erpBox.energy)

You might be asking yourself ``Why would I ever want to use a pointer when I could just use a variable?'' Well for one thing you can have one pointer and you can change what it points at. This is particularly useful if you are doing something like navigating some sort of structure (like a tree in memory).

In the next section we will see how to create variables in memory as we need them at run time instead of explicitly like the examples we showed you here. With this technique we will be able to create as many erp variables in memory as we need (perhaps in a loop) and just have one pointer to point at the particular erp variable we are interested in. This makes our code much simpler since we don't need huge numbers of variables or arrays around.



Next: Dynamic Allocation of Up: Introduction to C++ Previous: Enumeration Types


walter@
Wed Aug 10 11:53:26 PDT 1994