Previous: 12.1 Structures
Up: 12.1 Structures
Next: 12.1.2 Using Structure Tags
Previous Page: 12.1 Structures
Next Page: 12.1.2 Using Structure Tags
As with any data type, we need to be able to declare variables of
that type. In particular for structures, we must specify the names and types of
each of the fields of the structure.
So, to declare a structure, we need to describe
the number and types of fields in the form of a template,
as well as declare variables of that type.
We illustrate with an example:
a program that maintains
temperatures in both celsius and fahrenheit degrees. A variable, temp,
is to be used to maintain the equivalent temperatures in both celsius
and fahrenheit, and thus requires two fields, both of them integers.
We will call one field
ftemp for fahrenheit temperature and the other ctemp
for celsius. The program, shown in Figure 12.1,
reads a temperature to the ftemp field of the variable, temp,
and uses a function, f_to_c(),
to convert the temperature from fahrenheit to
celsius and store it in the ctemp field.
In looking at this program, we see that the variable temp is declared to be of structure type with the declaration statement:
struct trecd {
float ftemp;
float ctemp;
} temp;
This statement consists of the keyword, struct, followed by
the description of the template for the structure
and then the variable name.
The description of the template,
in our example, consists of a tag (or name), trecd
which names the template,
followed by a bracketed list of field declarations.
The tag is optional.
Within its scope, the tag can be used to refer to this
structure template without specifying the fields again, explicitly.
The bracketed list declares the fields of the structure
giving a type followed by an identifier. Our example
shows that this structure has two fields: ftemp and ctemp,
both of type float.
Figure 12.2 shows the memory cells allocated to the
variable temp.
Two float cells have been allocated, one referred to as the field and the other as ctemp. The entire block of memory is referred to by the variable name, temp. Otherwise, structure declarations are the same as any other variable declaration and have the same scope as would an int declaration, for example.
To access the information in a structure, the variable name (in our case, temp) is qualified using the ``dot'' operator ( .) followed by the field name:
temp.ftemp
temp.ctemp
In general, the syntax for accessing a member of a structure is:
In a program, members of a structure variable may be used just like other variables. In the function main() above, the argument to scanf() is &temp.ftemp which is the address of the float cell, temp.ftemp. (Precedence of the dot operator is higher than that of the address operator so no parentheses are needed in this case). The numeric value read by scanf() will be stored where the argument points - it will be stored in the cell temp.ftemp. The rest of the program is straight forward. We have passed a double value to the function f_to_c and get a double result which we assign to temp.ctemp and print the results.
Sample Session:
As we have said, the members of a structure variable can be of different types. For example:
struct {
char name[26];
int id_number;
} student;
which defines a structure variable, student, with two fields: a
string of characters called name, and an integer called id_number.
Enough contiguous memory
is allocated for the variable student to accommodate both fields.
We can find the amount of storage allocated for a structure by
using the sizeof operator. (Be aware that
the total size of a structure variable may not be equal to the sum of the
sizes for the fields because of rules about memory alignment which may
vary from computer to computer. For example,
memory allocation for an integer may have to start at a machine word boundary
such as an even byte address.
Such alignment requirements may make the size of a structure variable somewhat
greater than the sum of the field sizes).
The identifiers used for the field names apply only to variables of that structure type. Different structure types may have fields specified by the same identifier, but these are distinct cells, uniquely accessed by an appropriate structure variable name qualified by a field names. In addition, only field names declared in the structure template can be used to qualify a variable name. And finally, a field name may not be used by itself - it must always qualify an appropriate structure variable. Consider the following examples of structure variable declarations:
struct {
char f_name[10];
char m_inits[3];
char l_name[20];
int id_no;
int b_month;
int b_day;
int b_year;
} person, manager;
struct {
int id_no;
float cost;
float price;
} part;
Here we have declared two variables, person and manager,
to be structures with seven fields, some integers, some strings.
In this case, two separate instances of the template are allocated,
so person.id_no and manager.id_no are distinct storage cells.
We have also defined a variable, part, whose template also
has a id_no field name. But this is also a distinct storage
location accessed by part.id_no.
However,
with these declarations, it is NOT legal to refer to the cost field
of person ( person.cost) or the _day of a part
( part.b_day).
Similarly, referring to f_name or price is not legal
without a variable name of the appropriate type to be qualified.
Here are some legal examples of structure usage:
part.id_no = 99;
part.cost = .2239;
if (strcmp(person.f_name, "Helen") == 0)
printf("Last name is %s\n", person.l_name);
printf("This is the cost %d\n",part.cost);
part.price = part.cost * 2.0;
The only legal operations allowed on a structure variable are finding the address of the memory block using &, accessing its members, and copying or assigning it as a unit as long as the variables are of an identical structure type, for example:
manager = person;