You are on page 1of 3

C Primer Plus, Fourth Edition

By Stephen Prata

Table of Contents

Chapter 14. Structures and Other Data Forms

Pointers to Structures
Pointer lovers will be glad to know that you can have pointers to structures. There are at least three reasons why having
pointers to structures is a good idea. First, just as pointers to arrays are easier to manipulate (in a sorting problem, say) than
the arrays themselves, so pointers to structures are often easier to manipulate than structures themselves. Second, in some
older implementations, a structure can't be passed as an argument to a function, but a pointer to a structure can. Third, many
wondrous data representations use structures containing pointers to other structures.
The next short example (Listing 14.4) shows how to define a pointer to a structure and how to use it to access the members of
a structure.
Listing 14.4 The friends.c Program
/* friends.c -- uses pointer to a structure */
#include <stdio.h>
#define LEN 20
struct names {
char first[LEN];
char last[LEN];
} ;
struct guy {
struct names handle;
char favfood[LEN];
char job[LEN];
float income;
} ;
int main(void)
{
struct guy fellow[2] = {
{{ "Chip", "Vejer"} ,
"nachos plate",
"memory broker",
36827.00
},
{{"Rodney", "Swillbelly"} ,
"salmon mousse",
"tabloid editor",
148500.00
}
} ;
struct guy * him;
/* here is a pointer to a structure */
printf("address #1: %p #2: %p\n", &fellow[0], &fellow[1]);
him = &fellow[0];
/* tell the pointer where to point */
printf("pointer #1: %p #2: %p\n", him, him + 1);
printf("him->income is $%.2f: (*him).income is $%.2f\n",
him->income, (*him).income);
him++;
/* point to the next structure
*/
printf("him->favfood is %s: him->handle.last is %s\n",
him->favfood, him->handle.last);
return 0;
}
The output, please:

address #1: 0x0064fcb0 #2: 0x0064fd04


pointer #1: 0x0064fcb0 #2: 0x0064fd04him->income is $36827.00: (*him).income is
$36827.00
him->favfood is salmon mousse: him->handle.last is Swillbelly
Let's look first at how we created a pointer to a guy structure. Then we'll explain how to specify individual structure members
by using the pointer.

Declaring and Initializing a Structure Pointer


Declaration is as easy as can be:
struct guy * him;
First is the keyword struct, and then the structure tag guy, and then an * followed by the pointer name. The syntax is the
same as for the other pointer declarations you have seen.
This declaration does not create a new structure, but the pointer him can now be made to point to any existing structure of the
guy type. For instance, if barney is a structure of the guy type, you could do this:
him = &barney;
Unlike the case for arrays, the name of a structure is not the address of the structure; you need to use the & operator.
In the example, fellow is an array of structures, which means that fellow[0] is a structure, so the code initializes him
by making it point to fellow[0]:
him = &fellow[0];
The first two output lines show the success of this assignment. Comparing the two lines, you see that him points to
fellow[0], and him + 1 points to fellow[1]. Note that adding 1 to him adds 84 to the address. In hexadecimal, d04
c80 = 54 (hex) = 84 (base 10) because each guy structure occupies 84 bytes of memory: names.first is 20,
names.last is 20, favfood is 20, job is 20, and income is 4, the size of float on our system. Incidentally, on some
systems the size of a structure may be greater than the sum of its parts. That's because a system's alignment requirements for
data may cause gaps. For example, a system may have to place each member at an even addressor at an address that is a
multiple of four. Such structures might end up with unused "holes" in them.

Member Access by Pointer


The pointer him is pointing to the structure fellow[0]. How can you use him to get a value of a member of
fellow[0]? The third output line shows two methods.
The first method, and the most common, uses a new operator, ->. This operator is formed by typing a hyphen (-) followed by
the greater-than symbol (>). The example helps make the meaning clear:
him->income

is

fellow[0].income

if

him == &fellow[0]

In other words, a structure pointer followed by the -> operator works the same way as a structure name followed by the .
(dot) operator. (You can't properly say him.income because him is not a structure name.)
It is important to note that him is a pointer, but him->income is a member of the pointed-to structure. So in this case,
him->income is a float variable.
The second method for specifying the value of a structure member follows from this sequence: If him == &fellow[0],
then *him == fellow[0] because & and * are reciprocal operators. Hence, by substitution
fellow[0].income == (*him).income
The parentheses are required because the . operator has higher precedence than *.
In summary, if him is a pointer to a type guy structure named barney, the following are all equivalent:
barney.income == (*him).income == him->income

// assuming him == &barney

Now let's look at the interaction between structures and functions.

Top