home *** CD-ROM | disk | FTP | other *** search
- Chapter 11 - Structures and Unions
-
-
- WHAT IS A STRUCTURE?
-
- A structure is a user defined data type. You have the
-
- ability to define a new type of data considerably more
-
- complex than the types we have been using. A structure is a
-
- combination of several different previously defined data
-
- types, including other structures we have defined. An easy
-
- to understand definition is, a structure is a grouping of
-
- related data in a way convenient to the programmer or user
-
- of the program. The best way to understand a structure is
-
- to look at an example, so if you will load and display
-
- STRUCT1.C, we will do just that.
-
- The program begins with a structure definition. The
-
- key word "struct" is followed by some simple variables
-
- between the braces, which are the components of the
-
- structure. After the closing brace, you will find two
-
- variables listed, namely "boy", and "girl". According to
-
- the definition of a structure, "boy" is now a variable
-
- composed of three elements, "initial", "age", and "grade".
-
- Each of the three fields are associated with "boy", and each
-
- can store a variable of its respective type. The variable
-
- "girl" is also a variable containing three fields with the
-
- same names as those of "boy" but are actually different
-
- variables. We have therefore defined 6 simple variables.
-
- A SINGLE COMPOUND VARIABLE
-
- Lets examine the variable "boy" more closely. As
-
- stated above, each of the three elements of "boy" are simple
-
- variables and can be used anywhere in a C program where a
-
- variable of their type can be used. For example, the "age"
-
- element is an integer variable and can therefore be used
-
- anywhere in a C program where it is legal to use an integer
-
- variable, in calculations, as a counter, in I/O operations,
-
- etc. The only problem we have is defining how to use the
-
- simple variable "age" which is a part of the compound
-
- variable "boy". We use both names with a decimal point
-
- between them with the major name first. Thus "boy.age" is
-
- the complete variable name for the "age" field of "boy".
-
- This construct can be used anywhere in a C program that it
-
- is desired to refer to this field. In fact, it is illegal
-
- to use the name "boy" or "age" alone because they are only
-
- partial definitions of the complete field. Alone, the names
-
- refer to nothing.
-
- ASSIGNING VALUES TO THE VARIABLES
-
- Using the above definition, we can assign a value to
-
- each of the three fields of "boy" and each of the three
-
- fields of "girl". Note carefully that "boy.initial" is
-
-
-
- Page 73
-
-
-
-
-
-
-
-
-
- Chapter 11 - Structures and Unions
-
-
- actually a "char" type variable, because it was assigned
-
- that in the structure, so it must be assigned a character of
-
- data. Notice that "boy.initial" is assigned the character
-
- 'R' in agreement with the above rules. The remaining two
-
- fields of "boy" are assigned values in accordance with their
-
- respective types. Finally the three fields of girl are
-
- assigned values but in a different order to illustrate that
-
- the order of assignment is not critical.
-
- HOW DO WE USE THE RESULTING DATA?
-
- Now that we have assigned values to the six simple
-
- variables, we can do anything we desire with them. In order
-
- to keep this first example simple, we will simply print out
-
- the values to see if they really do exist as assigned. If
-
- you carefully inspect the "printf" statements, you will see
-
- that there is nothing special about them. The compound name
-
- of each variable is specified because that is the only valid
-
- name by which we can refer to these variables.
-
- Structures are a very useful method of grouping data
-
- together in order to make a program easier to write and
-
- understand. This first example is too simple to give you
-
- even a hint of the value of using structures, but continue
-
- on through these lessons and eventually you will see the
-
- value of using structures.
-
- Compile and run STRUCT1.C and observe the output.
-
- AN ARRAY OF STRUCTURES
-
- Load and display the next program named STRUCT2.C.
-
- This program contains the same structure definition as
-
- before but this time we define an array of 12 variables
-
- named "kids". This program therefore contains 12 times 3 =
-
- 36 simple variables, each of which can store one item of
-
- data provided that it is of the correct type. We also
-
- define a simple variable named "index" for use in the for
-
- loops.
-
- In order to assign each of the fields a value, we use a
-
- for loop and each pass through the loop results in assigning
-
- a value to three of the fields. One pass through the loop
-
- assigns all of the values for one of the "kids". This would
-
- not be a very useful way to assign data in a real situation,
-
- but a loop could read the data in from a file and store it
-
- in the correct fields. You might consider this the crude
-
- beginning of a data base, which it is.
-
- In the next few instructions of the program we assign
-
- new values to some of the fields to illustrate the method
-
-
-
- Page 74
-
-
-
-
-
-
-
-
-
- Chapter 11 - Structures and Unions
-
-
- used to accomplish this. It should be self explanatory, so
-
- no additional comments will be given.
-
- A NOTE TO PASCAL PROGRAMMERS
-
- Pascal allows you to copy an entire RECORD with one
-
- statement. This is not possible in C. You must copy each
-
- element of a structure one at a time. As improvements to
-
- the language are defined, this will be one of the
-
- refinements. In fact, some of the newer compilers already
-
- allow structure assignment. Check your compiler
-
- documentation to see if your compiler has this feature yet.
-
- WE FINALLY DISPLAY ALL OF THE RESULTS
-
- The last few statements contain a for loop in which all
-
- of the generated values are displayed in a formatted list.
-
- Compile and run the program to see if it does what you
-
- expect it to do.
-
- USING POINTERS AND STRUCTURES TOGETHER
-
- Load and display the file named STRUCT3.C for an
-
- example of using pointers with structures. This program is
-
- identical to the last program except that it uses pointers
-
- for some of the operations.
-
- The first difference shows up in the definition of
-
- variables following the structure definition. In this
-
- program we define a pointer named "point" which is defined
-
- as a pointer that points to the structure. It would be
-
- illegal to try to use this pointer to point to any other
-
- variable type. There is a very definite reason for this
-
- restriction in C as we have alluded to earlier and will
-
- review in the next few paragraphs.
-
- The next difference is in the for loop where we use the
-
- pointer for accessing the data fields. Since "kids" is a
-
- pointer variable that points to the structure, we can define
-
- "point" in terms of "kids". The variable "kids" is a
-
- constant so it cannot be changed in value, but "point" is a
-
- pointer variable and can be assigned any value consistent
-
- with its being required to point to the structure. If we
-
- assign the value of "kids" to "point" then it should be
-
- clear that it will point to the first element of the array,
-
- a structure containing three fields.
-
- POINTER ARITHMETIC
-
- Adding 1 to "point" will now cause it to point to the
-
- second field of the array because of the way pointers are
-
-
-
- Page 75
-
-
-
-
-
-
-
-
-
- Chapter 11 - Structures and Unions
-
-
- handled in C. The system knows that the structure contains
-
- three variables and it knows how many memory elements are
-
- required to store the complete structure. Therefore if we
-
- tell it to add one to the pointer, it will actually add the
-
- number of memory elements required to get to the next
-
- element of the array. If, for example, we were to add 4 to
-
- the pointer, it would advance the value of the pointer 4
-
- times the size of the structure, resulting in it pointing 4
-
- elements farther along the array. This is the reason a
-
- pointer cannot be used to point to any data type other than
-
- the one for which it was defined.
-
- Now to return to the program displayed on your monitor.
-
- It should be clear from the previous discussion that as we
-
- go through the loop, the pointer will point to the beginning
-
- of one of the array elements each time. We can therefore
-
- use the pointer to reference the various elements of the
-
- structure. Referring to the elements of a structure with a
-
- pointer occurs so often in C that a special method of doing
-
- that was devised. Using "point->initial" is the same as
-
- using "(*point).initial" which is really the way we did it
-
- in the last two programs. Remember that *point is the data
-
- to which the pointer points and the construct should be
-
- clear. The "->" is made up of the minus sign and the
-
- greater than sign.
-
- Since the pointer points to the structure, we must once
-
- again define which of the elements we wish to refer to each
-
- time we use one of the elements of the structure. There
-
- are, as we have seen, several different methods of referring
-
- to the members of the structure, and in the for loop used
-
- for output at the end of the program, we use three different
-
- methods. This would be considered very poor programming
-
- practice, but is done this way here to illustrate to you
-
- that they all lead to the same result. This program will
-
- probably require some study on your part to fully
-
- understand, but it will be worth your time and effort to
-
- grasp these principles.
-
- Compile and run this program.
-
- NESTED AND NAMED STRUCTURES
-
- Load and display the file named NESTED.C for an example
-
- of a nested structure. The structures we have seen so far
-
- have been very simple, although useful. It is possible to
-
- define structures containing dozens and even hundreds or
-
- thousands of elements but it would be to the programmers
-
- advantage not to define all of the elements at one pass but
-
- rather to use a hierarchical structure of definition. This
-
- will be illustrated with the program on your monitor.
-
-
-
- Page 76
-
-
-
-
-
-
-
-
-
- Chapter 11 - Structures and Unions
-
-
-
- The first structure contains three elements but is
-
- followed by no variable name. We therefore have not defined
-
- any variables only a structure, but since we have included a
-
- name at the beginning of the structure, the structure is
-
- named "person". The name "person" can be used to refer to
-
- the structure but not to any variable of this structure
-
- type. It is therefore a new type that we have defined, and
-
- we can use the new type in nearly the same way we use "int",
-
- "char", or any other types that exist in C. The only
-
- restriction is that this new name must always be associated
-
- with the reserved word "struct".
-
- The next structure definition contains three fields
-
- with the middle field being the previously defined structure
-
- which we named "person". The variable which has the type of
-
- "person" is named "descrip". So the new structure contains
-
- two simple variables, "grade" and a string named
-
- "lunch[25]", and the structure named "descrip". Since
-
- "descrip" contains three variables, the new structure
-
- actually contains 5 variables. This structure is also given
-
- a name "alldat", which is another type definition. Finally
-
- we define an array of 53 variables each with the structure
-
- defined by "alldat", and each with the name "student". If
-
- that is clear, you will see that we have defined a total of
-
- 53 times 5 variables, each of which is capable of storing a
-
- value.
-
- TWO MORE VARIABLES
-
- Since we have a new type definition we can use it to
-
- define two more variables. The variables "teacher" and
-
- "sub" are defined in the next statement to be variables of
-
- the type "alldat", so that each of these two variables
-
- contain 5 fields which can store data.
-
- NOW TO USE SOME OF THE FIELDS
-
- In the next five lines of the program, we will assign
-
- values to each of the fields of "teacher". The first field
-
- is the "grade" field and is handled just like the other
-
- structures we have studied because it is not part of the
-
- nested structure. Next we wish to assign a value to her age
-
- which is part of the nested structure. To address this
-
- field we start with the variable name "teacher" to which we
-
- append the name of the group "descrip", and then we must
-
- define which field of the nested structure we are interested
-
- in, so we append the name "age". The teachers status is
-
- handled in exactly the same manner as her age, but the last
-
- two fields are assigned strings using the string copy
-
- "strcpy" function which must be used for string assignment.
-
-
-
- Page 77
-
-
-
-
-
-
-
-
-
- Chapter 11 - Structures and Unions
-
-
- Notice that the variable names in the "strcpy" function are
-
- still variable names even though they are made up of several
-
- parts each.
-
- The variable "sub" is assigned nonsense values in much
-
- the same way, but in a different order since they do not
-
- have to occur in any required order. Finally, a few of the
-
- "student" variables are assigned values for illustrative
-
- purposes and the program ends. None of the values are
-
- printed for illustration since several were printed in the
-
- last examples.
-
- Compile and run this program, but when you run it you
-
- may get a "stack overflow" error. C uses it's own internal
-
- stack to store the automatic variables on but most C
-
- compilers use only a 2048 byte stack as a default. This
-
- program has more than that in the defined structures so it
-
- will be necessary for you to increase the stack size. The
-
- method for doing this for some compilers is given in the
-
- accompanying COMPILER.DOC file with this tutorial. Consult
-
- your compiler documentation for details about your compiler.
-
- There is another way around this problem, and that is to
-
- move the structure definitions outside of the program where
-
- they will be external variables and therefore static. The
-
- result is that they will not be kept on the internal stack
-
- and the stack will therefore not overflow. It would be
-
- good for you to try both methods of fixing this problem.
-
- MORE ABOUT STRUCTURES
-
- It is possible to continue nesting structures until you
-
- get totally confused. If you define them properly, the
-
- computer will not get confused because there is no stated
-
- limit as to how many levels of nesting are allowed. There
-
- is probably a practical limit of three beyond which you will
-
- get confused, but the language has no limit. In addition to
-
- nesting, you can include as many structures as you desire in
-
- any level of structures, such as defining another structure
-
- prior to "alldat" and using it in "alldat" in addition to
-
- using "person". The structure named "person" could be
-
- included in "alldat" two or more times if desired, as could
-
- pointers to it.
-
- Structures can contain arrays of other structures which
-
- in turn can contain arrays of simple types or other
-
- structures. It can go on and on until you lose all reason
-
- to continue. I am only trying to illustrate to you that
-
- structures are very valuable and you will find them great
-
- aids to programming if you use them wisely. Be conservative
-
- at first, and get bolder as you gain experience.
-
-
-
-
- Page 78
-
-
-
-
-
-
-
-
-
- Chapter 11 - Structures and Unions
-
-
- More complex structures will not be illustrated here,
-
- but you will find examples of additional structures in the
-
- example programs included in the last chapter of this
-
- tutorial. For example, see the "#include" file
-
- "STRUCT.DEF".
-
- WHAT ARE UNIONS?
-
- Load the file named UNION1.C for an example of a union.
-
- Simply stated, a union allows you a way to look at the same
-
- data with different types, or to use the same data with
-
- different names. Examine the program on your monitor.
-
- In this example we have two elements to the union, the
-
- first part being the integer named "value", which is stored
-
- as a two byte variable somewhere in the computers memory.
-
- The second element is made up of two character variables
-
- named "first" and "second". These two variables are stored
-
- in the same storage locations that "value" is stored in,
-
- because that is what a union does. A union allows you to
-
- store different types of data in the same physical storage
-
- locations. In this case, you could put an integer number in
-
- "value", then retrieve it in its two halves by getting each
-
- half using the two names "first" and "second". This
-
- technique is often used to pack data bytes together when you
-
- are, for example, combining bytes to be used in the
-
- registers of the microprocessor.
-
- Accessing the fields of the union are very similar to
-
- accessing the fields of a structure and will be left to you
-
- to determine by studying the example.
-
- One additional note must be given here about the
-
- program. When it is run using most compilers, the data will
-
- be displayed with two leading f's due to the hexadecimal
-
- output promoting the char type variables to int and
-
- extending the sign bit to the left. Converting the char
-
- type data fields to int type fields prior to display should
-
- remove the leading f's from your display. This will involve
-
- defining two new int type variables and assigning the char
-
- type variables to them. This will be left as an exercise
-
- for you. Note that the same problem will come up in a few
-
- of the later files also.
-
- Compile and run this program and observe that the data
-
- is read out as an "int" and as two "char" variables. The
-
- "char" variables are reversed in order because of the way an
-
- "int" variable is stored internally in your computer. Don't
-
- worry about this. It is not a problem but it can be a very
-
- interesting area of study if you are so inclined.
-
-
-
-
- Page 79
-
-
-
-
-
-
-
-
-
- Chapter 11 - Structures and Unions
-
-
- ANOTHER UNION EXAMPLE
-
- Load and display the file named UNION2.C for another
-
- example of a union, one which is much more common. Suppose
-
- you wished to build a large database including information
-
- on many types of vehicles. It would be silly to include the
-
- number of propellers on a car, or the number of tires on a
-
- boat. In order to keep all pertinent data, however, you
-
- would need those data points for their proper types of
-
- vehicles. In order to build an efficient data base, you
-
- would need several different types of data for each vehicle,
-
- some of which would be common, and some of which would be
-
- different. That is exactly what we are doing in the example
-
- program on your monitor.
-
- In this program, we will define a complete structure,
-
- then decide which of the various types can go into it. We
-
- will start at the top and work our way down. First, we
-
- define a few constants with the #defines, and begin the
-
- program itself. We define a structure named "automobile"
-
- containing several fields which you should have no trouble
-
- recognizing, but we define no variables at this time.
-
- A NEW CONCEPT, THE TYPEDEF
-
- Next we define a new type of data with a "typedef".
-
- This defines a complete new type that can be used in the
-
- same way that "int" or "char" can be used. Notice that the
-
- structure has no name, but at the end where there would
-
- normally be a variable name there is the name "BOATDEF". We
-
- now have a new type, "BOATDEF", that can be used to define a
-
- structure anyplace we would like to. Notice that this does
-
- not define any variables, only a new type definition.
-
- Capitalizing the name is a personal preference only and is
-
- not a C standard. It makes the "typedef" look different
-
- from a variable name.
-
- We finally come to the big structure that defines our
-
- data using the building blocks already defined above. The
-
- structure is composed of 5 parts, two simple variables named
-
- "vehicle" and "weight", followed by the union, and finally
-
- the last two simple variables named "value" and "owner". Of
-
- course the union is what we need to look at carefully here,
-
- so focus on it for the moment. You will notice that it is
-
- composed of four parts, the first part being the variable
-
- "car" which is a structure that we defined previously. The
-
- second part is a variable named "boat" which is a structure
-
- of the type "BOATDEF" previously defined. The third part of
-
- the union is the variable "airplane" which is a structure
-
- defined in place in the union. Finally we come to the last
-
-
-
-
-
- Page 80
-
-
-
-
-
-
-
-
-
- Chapter 11 - Structures and Unions
-
-
- part of the union, the variable named "ship" which is
-
- another structure of the type "BOATDEF".
-
- I hope it is obvious to you that all four could have
-
- been defined in any of the three ways shown, but the three
-
- different methods were used to show you that any could be
-
- used. In practice, the clearest definition would probably
-
- have occurred by using the "typedef" for each of the parts.
-
- WHAT DO WE HAVE NOW?
-
- We now have a structure that can be used to store any
-
- of four different kinds of data structures. The size of
-
- every record will be the size of that record containing the
-
- largest union. In this case part 1 is the largest union
-
- because it is composed of three integers, the others being
-
- composed of an integer and a character each. The first
-
- member of this union would therefore determine the size of
-
- all structures of this type. The resulting structure can be
-
- used to store any of the four types of data, but it is up to
-
- the programmer to keep track of what is stored in each
-
- variable of this type. The variable "vehicle" was designed
-
- into this structure to keep track of the type of vehicle
-
- stored here. The four defines at the top of the page were
-
- designed to be used as indicators to be stored in the
-
- variable "vehicle".
-
- A few examples of how to use the resulting structure
-
- are given in the next few lines of the program. Some of the
-
- variables are defined and a few of them are printed out for
-
- illustrative purposes.
-
- The union is not used too frequently, and almost never
-
- by beginning programmers. You will encounter it
-
- occasionally so it is worth your effort to at least know
-
- what it is. You do not need to know the details of it at
-
- this time, so don't spend too much time studying it. When
-
- you do have a need for a variant structure, a union, you can
-
- learn it at that time. For your own benefit, however, do not
-
- slight the structure. You should use the structure often.
-
-
-
-
-
-
-
- PROGRAMMING EXERCISES
-
- 1. Define a named structure containing a string field for
-
- a name, an integer for feet, and another for arms. Use
-
-
-
- Page 81
-
-
-
-
-
-
-
-
-
- Chapter 11 - Structures and Unions
-
-
- the new type to define an array of about 6 items. Fill
-
- the fields with data and print them out as follows.
-
- A human being has 2 legs and 2 arms.
- A dog has 4 legs and 0 arms.
- A television set has 4 legs and 0 arms.
- A chair has 4 legs and 2 arms.
- etc.
-
- 2. Rewrite exercise 1 using a pointer to print the data
-
- out.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 82
-