# 10.3: Structures, Arrays, and So On

We have seen that it is possible to have arrays within structures. It is also possible to have structures within structures and pointers within structures. Here are some examples:

/* The structure definitions */
struct foo {
float x;
float y;
};

struct bar {
double *pd;
struct foo littlefoo;
struct foo *pf;
};

/* The variable declarations */
struct foo my_foo;
struct bar my_bar;
struct bar *pbar = &my_bar;
double z=1.0;


The bar structure contains a pointer to a double, a pointer to struct foo, and a struct foo. We would access them as follows:

my_bar.pd = &z; /* pd isn’t a double but the address of one, hence & */
my_bar.littlefoo.x = 2.2;
pbar->littlefoo.y = 3.3;
pbar->pf = &my_foo;
pbar->pf->x = 4.4;


Note that if you didn’t say pbar->pf = &my_foo; first, then pbar->pf->x = 4.4; would be very evil! Without assigning my_foo to pf, this pointer would contain some random number. The second statement would then use that number as the starting address of struct foo, and write the number 4.4 where the x field should be. As it’s highly unlikely that this random number is the starting address of a struct foo, the number 4.4 overwrites something else. That might mean other data or even code gets destroyed. Your program behaves erratically or crashes.

Pointer Rule Number One

Never dereference1 an uninitialized pointer!

Only bad, evil things will happen and you will become a very sad programmer.

At the beginning of the transistor example we noted that we might want to create a bunch of transistors. One possibility is to use an array. There are other ways, as we shall see. Here’s how you’d declare an array of 1000 transistor structures, given the definition above:

struct transistor transistors[1000];


You would access the field as follows:

transistors[0].currentgain = 200.0; /* set 1st device’s gain to 200 */
transistors[2].breakdown = 85.0; /* set 3rd device’s breakdown to 85 */


Finally, it is also possible to create an array of pointers to transistor structures:

struct transistor *ptarray[1000];


Note that we do not have 1000 transistor structures, but rather 1000 pointers. Each of these would need to point to an appropriate transistor structure. Assuming you had declared one named my_transistor as we did earlier, you could write:

ptarray[0] = &my_transistor;


And you could access fields like so:

ptarray[0]->maxpower = 25.0;


Although this may look a little odd at first, this sort of construct does have some good uses in more advanced applications. To stretch your mind just a teensy bit further, C makes it possible to create something like an array of pointers to structures which contain a structure which in turn contains an array of pointers to still other structures. Read that again, imagine what that might look like as a memory map, and then write some possible definitions/declarations. If you can do that, you’ve pretty well mastered the idea.

1. i.e., try to access the fields of.