Previous Page TOC Next Page



- 17 -
Structure with struct


structure pointer operator


What You'll Learn


This unit teaches you how to build your own data types! In addition to the regular data types such as int, float, and double, you can now have data types called George, Paul, and Ringo if you want.

The most important reason for defining your own data types is to group other data types together. As a matter of fact, in a nutshell, that's what this unit is all about. Visual C++ gives you primary data types from which you can represent virtually any low-level value such as a single number, character, or string (through an array). After you finish this unit, you'll be able to define data types that are aggregate collections of Visual C++'s fundamental data types.



Sometimes, defining your own data types eliminates the need to program using parallel arrays. Instead of a parallel array that represents several types of data, you can define an array of your own data types that represents data. However, your excursion through parallel arrays was not in vain. Advanced Visual C++ programmers often create parallel arrays of their own data types to perform high-level data access.


Grouping in a Structure




Use the struct statement to define your own data types. struct tells Visual C++ to treat a collection of fundamental data types as a single data type from which you can define variables and arrays of variables.

Structures are a very important part of C++. In C, structures provided a way to represent a collection of data. In C++, structures are far more important because they are a fundamental building block to representing an object. A structure represents the data needed to describe an object. In the next lesson, you will explore the concepts behind object-oriented programming. But first, you will explore the mechanics of structures.

Arrays (and also pointers to data lists) are a powerful method of grouping a lot of data together, but they have one drawback: All data elements must be of the same data type. You can't create a 10-element array in which half the elements are integers and half are floating-point values.

There might be times, however, when such a mixed data-typed array would come in handy. A local television station wants to track its weekday broadcast audience (an int or long int) and the cost of each average airtime hour per day (a float). You'd need five integer values and five floating-point values, and you would pair two at a time for each day of the week. Two parallel arrays are the only means that you know of right now for achieving such a database.

Such combined data almost always works better and makes for easier coding when you store it in structures instead of parallel arrays. One of the easiest ways to begin thinking about structure data is to picture the 3x5 cardfiles you've seen or used. Such cardfiles usually contain names of contact people, their phone numbers, possibly their ages, and all sorts of other related but differently formatted data.

definition

A structure is a programmer-defined collection of other data types.



Structures are often called records in other programming languages and in database systems.

Another good example of the perfect data for Visual C++ structures is a stack of rental applications for an apartment. Each application contains the same format and collection of information: the prospective tenant's name, address, income, Social Security number, and so on. Each application contains completely different facts and figures, but they all have the same format.

When you define a structure, you define the format (similar to a blank form) of the data you want the structure to hold. When you ask Visual C++ to define a structure variable, Visual C++ makes a place in memory that combines all the data types in each structure member. The members in the structure correspond to each blank on a form. Through assignment statements, user input, and file input, programs initialize structure variables with unique data in each of the structure variable's fields.



Members are often called fields in other programming languages and in database systems.

Members of structures should have something in common with each other; they always should describe the same thing or object. This might be a real object or something imaginary. If you have several things you need to hold data for in your program, each of these things should have its own structure. If you own a car rental company and you want to have records describing your cars and your customers, you should have a structure for a car and a structure for your customer. If you had one structure, thinking that only one customer can rent a car at a time, you would soon run into trouble when a customer rented two cars. You would need to have the information about the customer in two places at once. What would you do with structures for cars that weren't rented? Hey, this isn't a data analysis course! Let's get on with structures. Just remember that a structure is more than just a convenient way of putting several data items together.

The struct Statement


When you define a structure, you tell Visual C++ exactly what format you want that structure to take. For example, suppose that your company currently keeps its inventory on 3x5 cards that look like the one in Figure 17.1. It would be your job to convert that cardfile system to a Visual C++ program.

Figure 17.1. Each cardfile contains the same structure.

definition

A member is an individual data value within a structure.

Each card in the cardfile has the same format. In other words, each card has a place for a product description, a retail price, and so on. Each card shares a uniform format, or structure, with the other cards. Each card contains the same details. Therefore, each card could be considered a structure variable, and each data item on each card would be a member of that structure variable. Your job is to convert the card into a structure, convert the card's items into members, and convert each card's facts and figures into data for the structure variables.

The first thing you must do to convert the cardfile to a program using Visual C++ structures is to determine the data types for each of the members. Table 17.1 lists good data type suggestions for the card inventory. If a data type is char *, that can mean either a character array holding a string or a character pointer pointing to a string.

You must decide in advance how much space to allow for each text member that will hold string data. You'll store each string member in an array, so you must decide in advance how long that array will be. Make the array long enough to hold the longest but most reasonable data value you expect. In other words, don't make the array too short, because you won't be able to hold needed descriptions, but at the same time, don't allow for a lot of unused space by making the array too large.

Table 17.1. The parts inventory members.

Member Name Data Type Length of String Description
partID char * 4 Unique part ID. No duplicates are allowed.
descrip char * 15 Description of the item.
quant int
Quantity in inventory currently.
retPrice float
Retail price.
whoPrice float
Wholesale price.
reorder int
Reorder quantity. When the quantity gets to this level, the item should be reordered.

If you were defining the data in Table 17.1 in separate variables, you might do so like this:


char partID[5];   // Leave room for the terminator

char descrip[16];

int quant;

float retPrice;

float whoPrice;

int reorder;

Instead of using separate variables, it would be nice to be able to refer to these items as a whole. When you pick up one of the 3x5 inventory cards, you're manipulating all the data at once. If you were to define a structure variable from these items, you could manipulate the single structure variable and treat the collection as a single entity instead of as six separate variables.

The struct statement defines structures. As mentioned earlier, when you define a structure, you don't actually define variables at that time. (Technically, there's a way to define both the structure and variables at once, but it's rarely done.) Defining structure variables requires two steps:

  1. Define the structure so that Visual C++ knows what the collection of data types in the structure looks like.

  2. Define one or more structure variables from that structure.

definition

A structure name is a name you can assign to a structure's format.

Here is the format of the struct statement that you must use when defining the format of data:


struct [structureName]

  {

    member definition;

    member definition;

    // One or more member definitions can follow

    member definition;

  };   // Remember the required semicolon!

Putting the inventory items in a structure definition is easy. All you have to do is take the separate variable definitions shown earlier and surround them with the opening and closing lines of the struct statement. You don't have to supply a structure name. The brackets around structureName in the format indicate that the name is optional. However, in C++ it is normal to use a name, and a name is required if you define the structure format in one place and a structure variable in another. You can think of a structure name as a data type name from now on. In C, structure names are called tags, so you might see this terminology elsewhere.

Here is an example of a structure definition for the inventory described earlier:


struct Invent           // Defines a new data type named invent

  {

    char partID[5];     // A part ID code. Leave room for the null zero.

    char descrip[16];   // A description of the item

    int quant;          // The number of items in the inventory

    float retPrice;     // Retail price

    float whoPrice;     // Wholesale price

    int reorder;        // Level reached before reordering

  };                    // The semicolon is required

Remember that this struct statement defines only the format of the structure, not the structure variable. After this struct statement executes, the program can define int variables, float variables, and also Invent variables. Before this struct, Visual C++ knew about the built-in data types, but it had no idea what an Invent data type was.



Put comments to the right of members to describe the data each member holds.

One thing to note about the struct statement is that it looks quite like a function definition without any code. However, a struct declaration is a statement in its own right, and it must have that final semicolon that all C++ statements have. Structure data types have their first letter capitalized to help distinguish them from variables.

Now that Visual C++ recognizes the Invent data type, you can use the structure tag Invent to define variables. The following statement defines three inventory structure variables:


Invent item, item2, item3;

When you define an integer variable, you precede the variable name with int like this:


int i;

When you define a structure variable, you precede the variable name with structureName, as done for the three inventory parts. Figure 17.2 shows what the variable item1 looks like. The boxes next to the members represent how many bytes of memory each member consumes using the Visual C++ compiler.

Figure 17.2. The format of the item1 structure variable.

What does Visual C++ put in the structure variable's members? The answer is the same as for any other kind of variable: Visual C++ doesn't put anything in the structure automatically. The structure will contain garbage. If you want data in the structure variable members, you have to put data in the structure variable, as described in the next section.

One nice advantage that C++ offers over C is that you don't have to use the struct keyword when defining structure variables. The following C-like definition is identical to the previous one:


struct Invent item, item2, item3;

Listing 17.1 doesn't contain a complete program, but it demonstrates how to define a structure for a radio station's listener database. Instead of defining individual, separately named structure variables, this program defines an array of structure variables.



The struct statement defines a structure and gives the structure a name used for defining variables from structures.

Input Listing 17.1. Defining an array of structure variables.

1:  // Filename: RADIOST.CPP

2:  // Defines a structure for a radio station listener

3:  // database and defines an array of structure

4:  // variables for that database

5:

6:  // Before defining structure variables,

7:  // you must define the structure's format

8:  struct RadioList

9:   {

10:     char listName[25];   // Listener name

11:    char dateFirst[9];   // Date first tuned in (i.e., 11/02/93)

12:    int age;

13:    char sex;

14:    int progSegment;     // Favorite daily program segment number

15:  };

16:

17:  void main()

18:  {

19:    struct RadioList listeners[100];   // Define 100 variables

20:    RadioList *owner;           // A pointer to a structure

21:                                // variable

22:  // Rest of program would follow


There is no output because this program is incomplete.

Analysis

You'll see the pattern in Listing 17.1 throughout your career as a Visual C++ programmer. Most Visual C++ programmers define their structures globally before the main() function. Remember that the structure definition doesn't define variables, so you won't be defining global variables just because the structure definition appears before main().



If you use the same structure definitions often, put them in their own header files and include them at the top of whatever programs need to define structure variables. If you must make a change to the structure definition, you can do so in one place without changing all the source code files that use the structures.

Line 19 uses the structure definition to define 100 occurrences of the listener variables in an array. (Of course, you could define 100 separately named variables, but that wouldn't be useful, as you already know.) Keep in mind, however, that line 19 defines a lot of data! Not only does line 19 define 100 variables, but each variable is actually a collection of five other member variables, two of which are also arrays. A single element of the listeners array, such as listeners[16], takes approximately 39 bytes of data!

You can't predict by adding individual data sizes exactly how much memory a structure variable will consume. Visual C++ might add hidden padding between members to help with memory organization. There is always only one way to determine the size of any data in Visual C++—by using the sizeof operator.

Figure 17.3 shows what the listeners array looks like. Each element in the array contains an individual set of five members that look like the RadioList structure's format.

Figure 17.3. The organization of the listeners array.

Line 20 of Listing 17.1 defines a pointer to a structure. Not only can you define pointers to the built-in data types, but you can also define pointers to the data types that you define. (You must first define the structure before defining a pointer to a structure that is not built-in.) You won't see the full advantage of using pointers to structures in this unit, but in the next unit you'll fully understand how pointers to your structures can help you manage memory effectively. If line 20 included the struct keyword, the results would be the same.

A pointer to a structure can point only to data with that particular format. In other words, if Listing 17.1 defined a second structure in addition to the listener structure, owner couldn't point to variables defined from that second structure; owner could point only to variables defined from the listeners structure.

Initializing Structure Variables




The dot operator and structure pointer operator access data of the members of structure variables.

There are two places in a program that you can initialize structure variables. You can initialize structure variables when you define them, and also in the body of the program through the usual mechanisms of assignment, user input, and file input.

Rarely will you initialize structures when you define them, but for completeness, you should know how to put data in structure variables at definition time. You'll see a pattern here, because you initialize structure variables the same way you initialize array data—using braces. The following struct defines a simple structure that contains a float, an int, and a char array:


struct S

  {

    float f;

    int i;

    char name[15];

  };   // Define the structure

To define a structure variable without initializing the data, you already know that this will work:


S aVar;

To assign and initialize at the same time you define the variable, do this:


S aVar = {10.5, 14, "Paul Jones"};

The order of the data in the braces must match the order of the members. This kind of assignment is available only at the time you define the structure variable, just as assigning a list of values to arrays is possible only when you define arrays.

If you want to define and initialize an array of structures, list the data values consecutively:


S aVars[3] = { {10.5, 14, "Paul Jones"},

               {73.4, 8, "Kim London"},

               {19.5, 56, "William Meck"}

             };

Each group of inner braces initializes a new structure variable.

You can't initialize structure variables directly using the literal braces once you've defined the variables.

Inside the program's body, assigning data to structures takes just a little more effort. You must learn about two new operators before you put data in structure variables. They are the dot operator and the structure pointer operator. Table 17.2 describes each of these operators.

Table 17.2. The structure access operators.

Operator Description
. Accesses data in a member of an individual structure variable.
-> Accesses data in a member of a structure pointed to by a pointer.

The dot operator and the structure pointer operator access data one member at a time. Therefore, if the structure variable contains 15 members, you'll need 15 statements to assign data to the entire structure variable.

Here is the format of the dot operator's usage:


structureVariableName.memberName

Here is the format of the structure pointer operator's usage:


pointerToStructure->memberName

You'll never see a structure variable on the left of the -> operator, only a pointer to a structure. That's how you know which to use. If you want to store data in a specific structure variable's member, use the dot operator. If you want to store data in a member of a structure that's pointed to by a structure pointer, use the -> operator.

Newcomers to Visual C++ programming often feel that the dot operator is easier to understand than the structure pointer operator. Part of the reason they feel this way is that they don't see the need for pointers to structures until they learn about dynamic memory allocation (which you'll learn about in the next unit). Until you get to the next unit, leave the -> alone and concentrate on the dot operator.

Here is the S structure definition:


struct S

  {

    float f;

    int i;

    char name[15];

  };   // Define the structure

Given this definition, if you were to define three nonarray variables like


S aVar1, aVar2, aVar3;   // Define three nonarray variables

you then could put data in the members of aVar1 like this:


aVar1.f = 12.34;   // Fills up the first member

aVar1.i = 23;      // Fills up the second member

strcpy(aVar1.name, "Sally Lake");   // Fills up the third member

When you grab the correct structure variable by putting it on the left side of the dot operator, the right side of the dot operator tells Visual C++ exactly which member from that particular operator is to be assigned. As usual, if you want to store data in character arrays, you'll have to use the strcpy() function, because you can't assign to arrays directly.

Here's some code that would fill the other two variables:


aVar2.f = 84.5;

aVar2.i = 3;

strcpy(aVar2.name, "Tim Deer");

aVar3.f = 56.3;

aVar3.i = 16;

aVar3.name[0] = 'A';

aVar3.name[1] = 'n';

aVar3.name[2] = 'n';

aVar3.name[3] = ' ';

aVar3.name[4] = 'H';

aVar3.name[5] = 'u';

aVar3.name[6] = 'f';

aVar3.name[7] = 'f';

aVar3.name[8] = '\0';

Do you understand the last few assignments? You don't have to assign strings to character arrays using strcpy(). If you like, you can store one character at a time. Just because the character array is part of a structure variable, that doesn't affect what you can do with the array. The existence of the structure variable simply affects how to get to the data, because you must preface the data with the name of the structure variable using the dot operator.

If an array of S variables was defined instead of separately named nonarray variables, the dot operator would work exactly as it does with nonarray variables. The only thing you must be sure of is to put the variable's subscript to the left of the dot, because the subscript goes with the structure variable and not with the member. For example, the following definition defines an array of three S variables:


S aVar[3];   // An array of three variables

The following code assigns each of these array elements the same data just assigned to the individual variables. However, the subscripts determine which structure variable is being assigned:


aVar[0].f = 12.34;   // Fills up the first member

aVar[0].i = 23;      // Fills up the second member

strcpy(aVar[0].name, "Sally Lake");   // Fills up the third member

aVar[1].f = 84.5;

aVar[1].i = 3;

strcpy(aVar[1].name, "Tim Deer");

aVar[2].f = 56.3;

aVar[2].i = 16;

aVar[2].name[0] = 'A';

aVar[2].name[1] = 'n';

aVar[2].name[2] = 'n';

aVar[2].name[3] = ' ';

aVar[2].name[4] = 'H';

aVar[2].name[5] = 'u';

aVar[2].name[6] = 'f';

aVar[2].name[7] = 'f';

aVar[2].name[8] = '\0';


Yikes! The last few assignments show subscripts on both sides of the dot operator. Nothing is really new here. The left side of the dot indicates which of the array structure variables is being assigned to, and the subscript on the right of the dot operator determines the member's individual element you're assigning to.

Just in case you're following this, I'll now confuse you further! There is nothing stopping you from having a structure that contains another structure in C++. You have already seen that a structure name can be thought of as a data type. Consider the following code:


struct Point

  {

    int x;

    int y;

  };

struct Rectangle

  {

     Point topLeft;

     Point bottomRight;

  };

Rectangle rect = {{10,10},{100,200}};

int left = rect.topLeft.x;

rect.bottomRight.y = 300;

rect.topLeft = rect.bottomRight; // !!! What does this do?

To access each level, you use the dot operator. So the first assignment reads "Using the variable rect, get me the member topLeft, and then using that member, get me the member x." In real programs, you might even have arrays of structures. The important thing to note is that you perform each member access in a right-to-left fashion, evaluating the result before going to the next level of member access. Note the braces in the initialization of the rect variable. Each level of structure can be initialized as a separate unit.



The dot operator lets you access the data of individual members of structure variables.


Structure Assignment




Structures can be assigned to other structures of the same type.

We have talked about structures being used as data types. You can do all sorts of operations with standard Visual C++ data types. With structures, you can see that you can't add and subtract them sensibly. Visual C++ does allow you to use the assignment operator (=) with them. So the following is sensible and acceptable:


struct S

  {

    char name[30];

    int  number;

  }

...

S iAmNotANumber = {"The Prisoner",6};

S numberOne;

numberOne = iAmNotANumber;

However, the following code is not allowed:


if (numberOne == iAmNotANumber)

Visual C++ always creates a default assignment operator if you do not create one (defining operators is beyond the scope of this book). On the other hand, Visual C++ does not create an equality operator for you. In fact, most operations are not allowed on structures by default; only assignment and copying (which are not quite the same thing in C++) are allowed. As far as you are concerned, the default assignment operator works by assigning each member one by one. For simple data this is just what you need. Sounds like there is a catch, right? There is! What happens if you assign a structure that contains a pointer? The pointer gets copied, not the data that the pointer points to. This means that you have two structures with a pointer pointing to the same data. In the next unit, you will explore some code that shows the problem.

Passing Structures As Parameters




Structures can be passed as parameters in the same way as any other data type.

A structure can be passed by value, by address, or by reference:


struct S

  {

    int x;

    int y;

  };

void AValueFunction(S s);

void AnAddressFunction(S *s);

void AReferenceFunction(S &s);

...

void main()

  {

    S sArg = {1,2};

    AValueFunction(sArg);

    AnAddressFunction(&sArg); // address of

    AReferenceFunction(sArg);

This code fragment shows that the parameters work just like any other standard data type. It is important to remember that a structure can hold a lot of data. Recall that pass by value creates a copy of the variable passed so that the called function can't change the original value. Creating a copy of a large structure will be inefficient. In fact, C++ invents a special operation to copy a structure. (By the way, I'm being pedantic here; there is a subtle difference between the assignment operator that I mentioned earlier and the copy function. You'll learn about how C++ does the copying in Lesson 10.) As you can see, if you have a structure with a pointer in a structure, the data accessed by the pointer can be changed, even when passed by value.

To avoid processing large amounts of data on the parameter list, you should always pass a structure by reference. Remember that by reference means that the called function is given the actual data of the argument, not a copy. Similarly, you can use the address operator. Lazy C++ programmers don't like typing all those pointers rather than dots, so they often prefer by reference. Once passed, the data would be accessed as follows for each of the previous functions:


void AValueFunction(S s)

  {

    int x = s.x;

  }

void AnAddressFunction(S *s)

  {

    int x = s->x;

  }

void AReferenceFunction(S &s)

  {

    int x = s.x;

  }


Remember that you can use the const keyword to ensure that reference or address parameters are not changed in the called function.

Those examples show you something else about scope. Note that C++ can tell the difference between the local variable x in the called functions and the x that belongs to the structure. The structure x's belong only to the structure and can't be accessed without reference to the structure name. C++ calls this new scope class scope because a structure is a special sort of a C++ class, which you will learn about in the next lesson.

Listing 17.2 contains a simple example of capturing data into a record and then displaying it, which explores the joys of structure passing and access.

Input Listing 17.2. A simple phone number database.

  1:// Filename: CONTACT.CPP

  2:// Store and show contacts

  3://

  4:#include <iostream.h>

  5:

  6:struct Contact

  7:  {

  8:     char name[50];

  9:     int  age;

 10:     char phoneNo[15];

 11:  };

 12:

 13:// Maximum number of contacts

 14:const int MAXCONTACTS = 10;

 15:

 16:// Prototypes

 17:int AddContact(Contact& contact);

 18:void DisplayContact(const Contact& contact);

 19:void DisplayAllContacts(const Contact contacts[MAXCONTACTS],int count);

 20:

 21:void main()

 22:  {

 23:    Contact contacts[MAXCONTACTS];

 24:    int count = 0;

 25:    while( count < MAXCONTACTS )// while more room

 26:      {

 27:         if (AddContact(contacts[count]))

 28:           count++;

 29:         else

 30:           break;

 31:      }

 32:    DisplayAllContacts(contacts,count);

 33:  }

 34://

 35:// DisplayContact displays a single name

 36://

 37:void DisplayContact(const Contact& contact)

 38:  {

 39:    cout << endl;

 40:    cout << "Name    : " << contact.name << endl;

 41:    cout << "Age     : " << contact.age << endl;

 42:    cout << "phone no: " << contact.phoneNo << endl;

 43:    cout << endl;

 44:  }

 45://

 46:// DisplayAllContacts calls DisplayContact to show

 47:// all entered names

 48:void DisplayAllContacts(const Contact contacts[MAXCONTACTS],

 49:                        int count)

 50:  {

 51:    for (int i = 0; i < count; i++)

 52:      {

 53:        DisplayContact(contacts[i]);

 54:      }

 55:  }

 56://

 57:// Add contact asks for one contact

 58://

 59:int AddContact(Contact& contact)

 60:  {

 61:    char answer;

 62:    cout << "Do you want to add a contact [Y]es/[N]o: ";

 63:    cin >> answer;

 64:    cin.ignore(80,'\n'); // skip rubbish

 65:

 66:    if (answer == 'y' || answer == 'Y')

 67:      {

 68:        cout << "Name: ";

 69:        cin.getline(contact.name,30);

 70:        cout << "Phone no: ";

 71:        cin.getline(contact.phoneNo,15);

 72:        cout << "Age ";

 73:        cin >> contact.age;

 74:        cin.ignore(80,'\n');

 75:        return 1;   // Added name ok

 76:      }

 77:    else

 78:      return 0;     // Did not add name

 79:   }

Output


Do you want to add a contact [Y]es/[N]o: y

Name: Stanley B. Lippman

Phone no: 0-201-54848-8

Age 20

Do you want to add a contact [Y]es/[N]o: y

Name: Robert Arnson

Phone no: 0-679-7921-3

Age 70

Do you want to add a contact [Y]es/[N]o: y

Name: Matthias Hansen

Phone no: +44 123 4567

Age 30

Do you want to add a contact [Y]es/[N]o: n

Name    : Stanley B. Lippman

Age     : 20

phone no: 0-201-54848-8

Name    : Robert Arnson

Age     : 70

phone no: 0-679-7921-3

Name    : Matthias Hansen

Age     : 30

phone no: +44 123 4567

Analysis

This program consists of a few very simple routines. For a start, notice how the structure makes it easy to pass around large amounts of data. The Contact structure defined in lines 6 through 11 contains three variables, but the parameter list of AddContact in line 17 only needs a single parameter. Structures do make it easy to handle large amounts of information.

The main program in lines 21 through 33 simply asks for as many contacts as possible, up to the maximum it can store. When the user has entered the maximum, or the user has entered all the data, the loop stops and the information is displayed. Note that line 27 uses the return value of AddContact (which only adds a single contact) to decide whether to increment the stored contact's count. It is very important to keep counts and arrays in synchronization. The clever part of C++ is that a reference can refer to an individual array member as well as a single declared value. This means that the code in AddContact in lines 68 to 73 that accesses the members does not need to know that there is an array of contacts. The routine would work well however you chose to store the contacts—even if it was part of another structure.

DisplayAllContacts passes the maximum number of items to be shown. With arrays, you must be careful to keep track of which members are valid. C++ cannot tell which elements have entries and which do not by default. You could put an indicator to show which entries are present and check each one. Again, in line 53, the routine takes advantage of the reference parameter to pass an individual contact to the DisplayContact function. By breaking the function up in this way, the code for displaying is much simplified and could be reused if you changed your mind about how the contact data was to be held.

AddContact and DisplayContact are good examples of simple object-oriented functions. They understand about the one object—the contact—and know how to perform a task with that object. In the next lesson, you'll see how you can associate data not only with structures, but also with functions.

Homework



General Knowledge


  1. What is a structure?

  2. What's one advantage of a structure over a parallel array?

  3. What are the individual names of a structure called?

  4. Answer the next five questions based on this structure definition:

    
    struct S
    
    {
    
      int i;
    
      char * c;
    
      char c2[100];
    
      float x;
    
      long int l;
    
    };

  5. A. How many structures are being defined?

    B. How many members are being defined?

    C. How many structure variables are being defined? If any, what are their names?

    D. How many structure names are being defined? If any, what are their names?

    E. Would you probably place this code locally or globally?

  6. Which two operators perform structure assignment?

  7. What's the advantage of defining a structure globally?

  8. What always appears on the right side of . or ->?

  9. What always appears on the left side of .?

  10. What always appears on the left side of ->?

  11. True or false: A struct statement defines the format of a structure but not a variable name.

  12. True or false: You can initialize a structure format when you define it.

  13. True or false: You can initialize a structure name when you define it.

  14. True or false: You can initialize a structure variable when you define it.

    What's the Output?


  15. Answer the next five questions based on this structure definition and initialization. Some have no valid answer, so be careful.

    
    struct Astruct
    
    {
    
      char c[10];
    
      char c2;
    
      int i;
    
      float x;
    
    };
    
    AStruct aVar = {"abc", 'X', 4, 34.3};

  16. A. What is the value of c?

    B. What is the value of aVar.c[2]?

    C. What is the value of aVar.x?

    D. What is the value of aVar[1].c?

    E. What is the value of aVar[1].c[4]?

    Find the Bug



  17. Study the following struct definition closely. What's missing?

    
    struct Book
    
    {
    
      char title[25];
    
      char author[16];
    
      int quant;
    
      float retPrice;
    
      float whoPrice;
    
    }

  18. After you fixed the preceding struct, John J. Johnson decided to write a program using the structure. He defined a Book variable like this:


    
    Book myBook;

    John then decided to store data in the variable one member at a time. However, he ran into a problem with this statement:


    
    strcpy(title.myBook, "A Thousand Tales");

    See if you can help him.

    Write Code That. . .


  19. Add error checking to the CONTACT.CPP program in Listing 17.2 so that the user has to enter a sensible age in response to the AddContact age query. As it now stands, the program doesn't contain error checking for the age.

  20. Write a program that keeps track of Olympic skaters' names and scores. Use an array of eight structure variables to keep track of the eight competitors. Initialize the information when you define the variables. Print the average scores (assume that the scores can range from 0.0 to 10.0), the name of the skater with the highest scores, the name of the skater with the lowest scores, and the name of the skater who makes the most from television movies about her life (just kidding!).

    Extra Credit


  21. Rewrite the parts inventory system described in Listing 15.2 (INVENT.CPP) using an Inventory structure, like one described in this unit, rather than parallel arrays. Before letting the user add an item to the inventory, check to see whether that part ID already exists. If it does, display an error message and redisplay the menu. By checking for duplicate part IDs, you disallow duplicate keys in the array.

Previous Page Page Top TOC Next Page