Now for a concrete example. A typical structure definition may look something like this:

struct Marmot (
struct Marmot *NextMarmot;
float Age;
float Weight;
};


We could declare three instances of Marmots and link them together as follows:

struct Marmot Larry = { 0, 3.4, 19.7 };
struct Marmot Jane = { &Larry, 2.5, 13.1 };
struct Marmot Felix = { &Jane, 2.9, 15.6 };


Felix is at the top of the list, while Larry is at the bottom. Note that the items must be declared in inverse order since the pointer reference must exist prior to assignment (i.e., Jane must exist in order for Felix to use Jane's address). It is common to also declare a pointer to use as the head of the list. Thus, we might also add:

struct Marmot *MarmotList = &Felix;


Thus, the following are true:

• Felix.NextMarmot points to Jane
• MarmotList->NextMarmot points to Jane
• Jane.NextMarmot points to Larry
• MarmotList->NextMarmot->NextMarmot points to Larry
• Larry.NextMarmot is 0
• MarmotList->NextMarmot->NextMarmot->NextMarmot is 0

The final line of pointers to pointers is not very practical. To get around this, we can use a temporary pointer. Below is an example function that takes the head of a Marmot list as its argument, and then prints out the ages of all of the Marmots in the list.

void PrintMarmotAges( struct Marmot *top )
{
struct Marmot *temp;

temp = top; /* initialize pointer to top of list */

while( temp ) /* true only if marmot exists */
{
printf( "%f\n", temp->Age );
temp = temp->NextMarmot );
}
}


It would be called like so:

PrintMarmotAges( MarmotList );


Note that we could've reused top rather than use the local temp in this case. If the head of the list will be needed for something else in the function though, then the local variable will be required (i.e., since temp = temp->NextMarmot effectively erases the prior value of temp, we lose the head of the list as we walk down the list).