home *** CD-ROM | disk | FTP | other *** search
-
-
-
-
- Chapter 11
- STRUCTURES AND UNIONS
-
-
- WHAT IS A STRUCTURE?
- ____________________________________________________________
-
- A structure is a user defined data type. ===============
- Using a structure you have the ability to STRUCT1.C
- 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. A simple 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 keyword
- 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 variable names listed, 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 named 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 named 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. We now
- have the problem of defining how to use the simple variable
- named age which is a part of the compound variable named boy.
- To do so 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. (Actually
- the name boy alone does have meaning when used with some of
- the newest C compilers. We will discuss this later.)
-
- Page 11-1
-
- Chapter 11 - Structures and Unions
-
- 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 actually a char type
- variable, because it was assigned that in the structure, so
- it must be assigned a character of data. In line 13,
- 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 STRUCT2.C
- structure definition as before but this time ===============
- we define an array of 12 variables named
- kids. It should be clear that this program
- 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
-
- Page 11-2
-
- Chapter 11 - Structures and Unions
-
- 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 used to
- accomplish this. It should be self explanatory, so no
- additional comments will be given.
-
-
- A RECENT UPGRADE TO THE C LANGUAGE
- ____________________________________________________________
-
- Most modern C compilers will allow you to copy an entire
- structure with one statement. This is a fairly recent
- addition to the C language and is a part of the ANSI standard,
- so you should feel free to use it with your C compiler if it
- is available. Line 24 is an example of using a structure
- assignment. In this statement, all 3 fields of kids[4] are
- copied into their respective fields of kids[10].
-
-
- 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. You will need to remove line 24 if your compiler does not
- support structure assignments.
-
-
- USING POINTERS AND STRUCTURES TOGETHER
- ____________________________________________________________
-
- Examine the file named STRUCT3.C for an =============
- example of using pointers with structures. STRUCT3.C
- 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. Recall from chapter
- 8 of this tutorial that we said that the name of an array is
- actually a pointer to the first element of the array. Since
-
- Page 11-3
-
- Chapter 11 - Structures and Unions
-
- kids is a pointer variable that points to the first element
- of the array which is a 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 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 stored 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.
-
- Lines 31 and 32 are two additional examples of structure
- assignment for your benefit. Compile and run this program,
-
- Page 11-4
-
- Chapter 11 - Structures and Unions
-
- and once again, if your compiler does not support structure
- assignment, you will need to remove lines 31 and 32.
-
-
- NESTED AND NAMED STRUCTURES
- ____________________________________________________________
-
- Examine the file named NESTED.C for an ==============
- example of a nested structure. The NESTED.C
- 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 definition.
- This will be illustrated with the program on your monitor.
-
- 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 keyword 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, 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 the type 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 line 19 to be variables of the type alldat, so that each
- of these two variables contain 5 fields in which we can store
- data.
-
-
-
-
- Page 11-5
-
- Chapter 11 - Structures and Unions
-
- NOW TO USE SOME OF THE FIELDS
- ____________________________________________________________
-
- In lines 21 through 25 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 variable 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 function strcpy() which must be
- used for string assignment. 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 its own internal stack to
- store the automatic variables on, but some C compilers use
- only a 2048 byte stack as a default. This program requires
- more than that for the defined structures so it will be
- necessary for you to increase the stack size. Consult your
- compiler documentation for details concerning the method of
- increasing the stack size. There is no standard way to do
- this. There is another way around this problem, and that is
- to move the structure and variable 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 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
-
- Page 11-6
-
- Chapter 11 - Structures and Unions
-
- 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.
-
- 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 named STRUCT.DEF on the
- distribution disk.
-
-
- WHAT ARE UNIONS?
- ____________________________________________________________
-
- Examine the file named UNION1.C for an ==============
- example of a union. Simply stated, a union UNION1.C
- allows you a way to look at the same data ==============
- with different types, or to use the same data
- with different names.
-
- 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 some C 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
-
- Page 11-7
-
- Chapter 11 - Structures and Unions
-
- problem will come up in a few of the later files in this
- tutorial.
-
- Compile and run this program and observe that the data is read
- out as an int and as two char variables. The char variables
- may be reversed in order because of the way an int variable
- is stored internally in your computer. If your system
- reverses these variables, don't worry about it. It is not a
- problem but it can be a very interesting area of study if you
- are so inclined.
-
-
- ANOTHER UNION EXAMPLE
- ____________________________________________________________
-
- Load and display the file named UNION2.C for ==============
- another example of a union, one which is much UNION2.C
- 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. 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
-
- Page 11-8
-
- Chapter 11 - Structures and Unions
-
- 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 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 named 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 named 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.
-
-
-
- Page 11-9
-
- Chapter 11 - Structures and Unions
-
- WHAT IS A BITFIELD?
- ____________________________________________________________
-
- Load and display the program named BITFIELD.C ==============
- for an example of how to define and use a BITFIELD.C
- bitfield, a relatively new addition to the ==============
- programming language C. In this program, we
- have a union made up of a single int type
- variable in line 7 and the structure defined in lines 8
- through 12. The structure is composed of three bitfields
- named x, y, and z. The variable named x is only one bit wide,
- the variable y is two bits wide and adjacent to the variable
- x, and the variable z is two bits wide and adjacent to y.
- Moreover, because the union causes the bits to be stored in
- the same memory location as the variable index, the variable
- x is the least significant bit of the variable index, y is the
- next two bits, and z is stored in the next two bits of index.
-
- Compile and run the program and you will see that as the
- variable index is incremented by 1 each time you will see the
- bitfields of the union counting due to their respective
- locations within the int definition. Note that your compiler
- may not support the bitfield since it is a relatively new
- construct to the C programming language.
-
- One thing must be pointed out, the bitfields must be defined
- as parts of an unsigned int or your compiler will issue an
- error message.
-
-
- WHAT IS THE BITFIELD GOOD FOR?
- ____________________________________________________________
-
- The bitfield is very useful if you have a lot of data to
- separate into individual bits or groups of bits. Many systems
- use some sort of a packed format to get lots of data stored
- in a few bytes. Your imagination is your only limitation to
- use of this feature of C.
-
- PROGRAMMING EXERCISES
- ____________________________________________________________
-
- 1. Define a named structure containing a string for a name,
- an integer for feet, and another for arms. Use 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 11-10