An Application that Calls a DLL

Chapter 13 - Structures, Unions, and Miscellaneous Items

Visual C++ 6: The Complete Reference
Chris H. Pappas and William H. Murray, III
  Copyright 1998 The McGraw-Hill Companies

Structures
The notion of a data structure is a very familiar idea in everyday life. A card file containing friends’ addresses, telephone numbers, and so on, is a structure of related items. A file of favorite CDs or LP records is a structure. A computer’s directory listing is a structure. These are examples that use a structure, but what is a structure? Literally, a structure can be thought of as a group of variables, which can be of different types, held together in a single unit. The single unit is the structure.
Structures: Syntax and Rules
A structure is formed in C or C++ by using the keyword struct, followed by an optional tag field, and then a list of members within the structure. The optional tag field is used to create other variables of the particular structure’s type. The syntax for a structure with the optional tag field looks like this:
struct tag_field {
 
member_type member1;
 
member_type member2;
 
member_type member3;
        .
        .
        .
 
member_type member n;
};
A semicolon terminates the structure definition because it is actually a C and C++ statement. Several of the example programs in this chapter use a structure similar to the following:
struct stboat {
 char sztype [iSTRING15 + iNULL_CHAR];
 char szmodel[iSTRING15 + iNULL_CHAR];
 char sztitle[iSTRING20 + iNULL_CHAR];
 int iyear;
 long int lmotor_hours;
 float fsaleprice;
};
The structure is created with the keyword struct followed by the tag field or type for the structure. In this example, stboat is the tag field for the structure.
This structure declaration contains several members; sztype, szmodel, and sztitle are null-terminated strings of the specified length. These strings are followed by an integer, iyear, a long integer, lmotor_hours, and a float, fsaleprice. The structure will be used to save sales information for a boat.
So far, all that has been defined is a new hypothetical structure type called stboat. However, no variable has been associated with the structure at this point. In a program, you can associate a variable with a structure by using a statement similar to the following:
struct stboat stused_boat;
The statement defines stused_boat to be of the type struct stboat. Notice that the declaration required the use of the structure’s tag field. If this statement is contained within a function, then the structure, named stused_boat, is local in scope to that function. If the statement is contained outside of all program functions, the structure will be global in scope. It is also possible to declare a structure variable using this syntax:
struct stboat {
 char sztype [iSTRING15 + iNULL_CHAR];
 char szmodel[iSTRING15 + iNULL_CHAR];
 char sztitle[iSTRING20 + iNULL_CHAR];
 int iyear;
 long int lmotor_hours;
 float fsaleprice;
} stused_boat;
Here, the variable declaration is sandwiched between the structure’s closing brace (}) and the required semicolon (;). In both examples, stused_boat is declared as structure type stboat. Actually, when only one variable is associated with a structure type, the tag field can be eliminated, so it would also be possible to write
struct {
 char sztype [iSTRING15 + iNULL_CHAR];
 char szmodel[iSTRING15 + iNULL_CHAR];
 char sztitle[iSTRING20 + iNULL_CHAR];
 int iyear;
 long int lmotor_hours;
 float fsaleprice;
} stused_boat;
Notice that this structure declaration does not include a tag field and creates what is called an anonymous structure type. While the statement does define a single variable, stused_boat, there is no way the application can create another variable of the same type somewhere else in the application. Without the structure’s tag field, there is no syntactically legal way to refer to the new type. However, it is possible to associate several variables with the same structure type without specifying a tag field, as shown in the following listing:
struct {
 char sztype [iSTRING15 + iNULL_CHAR];
 char szmodel[iSTRING15 + iNULL_CHAR];
 char sztitle[iSTRING20 + iNULL_CHAR];
 int iyear;
 long int lmotor_hours;
 float fsaleprice;
} stboat1,stboat2,stboat3;
The compiler allocates all necessary memory for the structure members, as it does for any other variable. To decide if your structure declarations need a tag field, ask yourself the following questions: “Will I need to create other variables of this structure type somewhere else in the program?” and “Will I be passing the structure type to functions?” If the answer to either of these questions is yes, you need a tag field.
C++ Structures: Additional Syntax and Rule Extensions
C++, in many cases, can be described as a superset of C. In general, this means that what works in C should work in C++.
  Note Using C design philosophies in a C++ program often ignores C++’s streamlining enhancements.
The structure declaration syntax styles just described all work with both the C and C++ compilers. However, C++ has one additional method for declaring variables of a particular structure type. This exclusive C++ shorthand notation eliminates the need to repeat the keyword struct. The following example highlights this subtle difference:
/* legal C and C++ structure declaration syntax */
struct stboat stused_boat;

// exclusive C++ structure declaration syntax
stboat stused_boat;
Accessing Structure Members
Individual members can be referenced within a structure by using the dot or member operator (.). The syntax is
stname.mname
Here, stname is the variable associated with the structure type and mname is the name of any member variable in the structure.
In C, for example, information can be placed in the szmodel member with a statement such as
gets(stused_boat.szmodel);
Here, stused_boat is the name associated with the structure and szmodel is a member variable of the structure. In a similar manner, you can use a printf( ) function to print information for a structure member:
printf(“%ld”,stused_boat.lmotor_hours);
The syntax for accessing structure members is basically the same in C++:
cin >> stused_boat.sztype;
This statement will read the make of the stused_boat into the character array, while the next statement will print the stused_boat selling price to the screen:
cout << stused_boat.fsaleprice;
Structure members are handled like any other C or C++ variable with the exception that the dot operator must always be used with them.
Constructing a Simple Structure
In the following example, you will see a structure similar to the stboat structure given earlier in this chapter. Examine the listing to see if you understand how the various structure elements are accessed by the program:
/*
*   struct.c
*   C program illustrates how to construct a structure.
*   Program stores data about your boat in a C structure.
*   Copyright (c) Chris H. Pappas and William H. Murray, 1997
*/

#include <stdio.h>

#define iSTRING15 15
#define iSTRING20 20
#define iNULL_CHAR 1

struct stboat {
 char sztype [iSTRING15 + iNULL_CHAR];
 char szmodel[iSTRING15 + iNULL_CHAR];
 char sztitle[iSTRING20 + iNULL_CHAR];
 int iyear;
 long int lmotor_hours;
 float fsaleprice;
} stused_boat;

int main(void)
{
 printf(“\nPlease enter the make of the boat: ”);
 gets(stused_boat.sztype);

 printf(“\nPlease enter the model of the boat: ”);
 gets(stused_boat.szmodel);

 printf(“\nPlease enter the title number for the boat: ”);
 gets(stused_boat.sztitle);

 printf(“\nPlease enter the model year for the boat: ”);
 scanf(“%d”,&stused_boat.iyear);

 printf(“\nPlease enter the current hours on ”);
 printf(“the motor for the boat: ”);
 scanf(“%ld”,&stused_boat.lmotor_hours);

 printf(“\nPlease enter the purchase price of the boat: ”);
 scanf(“%f”,&stused_boat.fsaleprice);

 printf(“\n\n\n”);
 printf(“A %d %s %s with title number #%s\n”,
    stused_boat.iyear,stused_boat.sztype,
    stused_boat.szmodel,stused_boat.sztitle);
 printf(“currently has %ld motor hours”,
    stused_boat.lmotor_hours);
 printf(“ and was purchased for $%8.2f\n”,
    stused_boat.fsaleprice);

 return (0);
}
The output from the preceding example shows how information can be manipulated with a structure:
A 1952 Chris Craft with title number #CC1011771018C
currently has 34187 motor hours and was purchased for $68132.98
You might notice, at this point, that stused_boat has a global file scope since it was declared outside of any function.
Passing Structures to Functions
It is often necessary to pass structure information to functions. When a structure is passed to a function, the information is passed call-by-value. Since only a copy of the information is being passed in, it is impossible for the function to alter the contents of the original structure. You can pass a structure to a function by using the following syntax:
fname(stvariable);
If stused_boat was made local in scope to main( ), and if you move its declaration inside the function, it could be passed to a function named vprint_data( ) with the statement
vprint_data(stused_boat);
The vprint_data( ) prototype must declare the structure type it is about to receive, as you might suspect:
/* legal C and C++ structure declaration syntax */
void vprint_data(struct stboat stany_boat);

// exclusive C++ structure declaration syntax
void vprint_data(stboat stany_boat);
Passing entire copies of structures to functions is not always the most efficient way of programming. Where time is a factor, the use of pointers might be a better choice. If saving memory is a consideration, the malloc( ) function for dynamically allocating structure memory in C when using linked lists is often used instead of statically allocated memory. You’ll see how this is done in the next chapter.
The next example shows how to pass a complete structure to a function. Notice that it is a simple modification of the last example. The next four example programs use the same basic approach. Each program modifies only that portion of the algorithm necessary to explain the current subject. This approach will allow you to easily view the code and syntax changes necessary to implement a particular language feature. Study the listing and see how the structure, stused_boat, is passed to the function vprint_data( ).
/*
*   passst.c
*   C program shows how to pass a structure to a function.
*   Copyright (c) Chris H. Pappas and William H. Murray, 1997
*/

#include <stdio.h>

#define iSTRING15 15
#define iSTRING20 20
#define iNULL_CHAR 1

struct stboat {
 char sztype [iSTRING15 + iNULL_CHAR];
 char szmodel[iSTRING15 + iNULL_CHAR];
 char sztitle[iSTRING20 + iNULL_CHAR];
 int iyear;
 long int lmotor_hours;
 float fsaleprice;
};

void vprint_data(struct stboat stany_boat);
int main(void)
{
 struct stboat stused_boat;

 printf(“\nPlease enter the make of the boat: ”);
 gets(stused_boat.sztype);

 printf(“\nPlease enter the model of the boat: ”);
 gets(stused_boat.szmodel);

 printf(“\nPlease enter the title number for the boat: ”);
 gets(stused_boat.sztitle);

 printf(“\nPlease enter the model year for the boat: ”);
 scanf(“%d”,&stused_boat.iyear);

 printf(“\nPlease enter the current hours on ”);
 printf(“the motor for the boat: ”);
 scanf(“%ld”,&stused_boat.lmotor_hours);

 printf(“\nPlease enter the purchase price of the boat: ”);
 scanf(“%f”,&stused_boat.fsaleprice);

 vprint_data(stused_boat);

 return (0);
}
void vprint_data(struct stboat stany_boat)
{
 printf(“\n\n”);
 printf(“A %d %s %s with title number #%s\n”,stany_boat.iyear,
    stany_boat.sztype,stany_boat.szmodel,stany_boat.sztitle);
 printf(“currently has %ld motor hours”,stany_boat.lmotor_hours);
 printf(“ and was purchased for $%8.2f”,
        stany_boat.fsaleprice);
}
In this example, an entire structure was passed-by-value to the function. The calling procedure simply invokes the function by passing the structure variable, stused_boat. Notice that the structure’s tag field, stboat, was needed in the vprint_data( ) function prototype and declaration. As you will see later in this chapter, it is also possible to pass individual structure members by value to a function. The output from this program is similar to the previous example.
Constructing an Array of Structures
A structure can be thought of as similar to a single card from a card file. The real power in using structures comes about when a collection of structures, called an array of structures, is used. An array of structures is similar to a whole card file containing a great number of individual cards. If you maintain an array of structures, a database of information can be manipulated for a wide range of items.
This array of structures might include information on all of the boats at a local marina. It would be practical for a boat dealer to maintain such a file and be able to pull out of a database all boats on the lot selling for less than $45,000 or all boats with a minimum of one stateroom. Study the following example and note how the code has been changed from earlier examples:
/*
*   stcary.c
*   C program uses an array of structures.
*   This example creates a “used boat inventory” for
*   Nineveh Boat Sales.
*   Copyright (c) Chris H. Pappas and William H. Murray, 1997
*/

#include <stdio.h>

#define iSTRING15 15
#define iSTRING20 20
#define iNULL_CHAR 1
#define iMAX_BOATS 50
struct stboat {
 char sztype [iSTRING15 + iNULL_CHAR];
 char szmodel[iSTRING15 + iNULL_CHAR];
 char sztitle[iSTRING20 + iNULL_CHAR];
 char szcomment[80];
 int iyear;
 long int lmotor_hours;
 float fretail;
 float fwholesale;
};

int main(void)
{
 int i,iinstock;
 struct stboat astNineveh[iMAX_BOATS];

 printf(“How many boats in inventory? ”);
 scanf(“%d”,&iinstock);

 for (i=0; i<iinstock; i++) {

   flushall( );     /
* flush keyboard buffer */
   printf(“\nPlease enter the make of the boat: ”);
   gets(astNineveh[i].sztype);

   printf(“\nPlease enter the model of the boat: ”);
   gets(astNineveh[i].szmodel);

   printf(“\nPlease enter the title number for the boat: ”);
   gets(astNineveh[i].sztitle);

   printf(“\nPlease enter a one line comment about the boat: ”);
   gets(astNineveh[i].szcomment);

   printf(“\nPlease enter the model year for the boat: ”);
   scanf(“%d”,&astNineveh[i].iyear);
   printf(“\nPlease enter the current hours on ”);
   printf(“the motor for the boat: ”);
   scanf(“%ld”,&astNineveh[i].lmotor_hours);

   printf(“\nPlease enter the retail price of the boat :”);
   scanf(“%f”,&astNineveh[i].fretail);

   printf(“\nPlease enter the wholesale price of the boat :”);
   scanf(“%f”,&astNineveh[i].fwholesale);
 }

 printf(“\n\n\n”);

 for (i=0; i<iinstock; i++) {
   printf(“A %d %s %s beauty with %ld low hours.\n”,
          astNineveh[i].iyear,astNineveh[i].sztype,
          astNineveh[i].szmodel,astNineveh[i].lmotor_hours);
   printf(“%s\n”,astNineveh[i].szcomment);
   printf(
      “Grab the deal by asking your Nineveh salesperson for”);
   printf(“ #%s ONLY! $%8.2f.\n”,astNineveh[i].sztitle,
          astNineveh[i].fretail);
   printf(“\n\n”);
 }

 return (0);
}
Here, Nineveh Boat Sales has an array of structures set up to hold information about the boats in the marina.
The variable astNineveh[iMAX_BOATS] associated with the structure, struct stboat, is actually an array. In this case, iMAX_BOATS sets the maximum array size to 50. This simply means that data on 50 boats can be maintained in the array of structures. It will be necessary to know which of the boats in the file you wish to view. The first array element is zero. Therefore, information on the first boat in the array of structures can be accessed with a statement such as
gets(astNineveh[0].sztitle);
As you study the program, notice that the array elements are accessed with the help of a loop. In this manner, element members are obtained with code, such as the following:
gets(astNineveh[i].sztitle);
The flushall( ) statement inside the for loop is necessary to remove the newline left in the input stream from the previous scanf( ) statements (the one before the loop is entered and the last scanf( ) statement within the loop). Without the call to flushall( ), the gets( ) statement would be skipped over. Remember, gets( ) reads everything up to and including the newline. Both scanf( ) statements leave the newline in the input stream. Without the call to flushall( ), the gets( ) statement would simply grab the newline from the input stream and move on to the next executable statement.
The previous program’s output serves to illustrate the small stock of boats on hand at Nineveh Boat Sales. It also shows how structure information can be rearranged in output statements:
A 1957 Chris Craft Dayliner 124876 low hours.
A great riding boat owned by a salesperson.
Grab the deal by asking your Nineveh salesperson for
#BS12345BFD ONLY! $36234.00.

A 1988 Starcraft Weekender a beauty with 27657 low hours.
Runs and looks great. Owned by successful painter.
Grab the deal by asking your Nineveh salesperson for
#BG7774545AFD ONLY! $18533.99.

A 1991 Scarab a wower with 1000 low hours.
A cheap means of transportation. Owned by grandfather.
Grab the deal by asking your Nineveh salesperson for
#156AFG4476 ONLY! $56999.99.
When you are working with arrays of structures, be aware of the memory limitations of the system you are programming on—statically allocated memory for arrays of structures can require large amounts of system memory.
Using Pointers to Structures
In the following example, an array of structures is created in a similar manner to the last program. The arrow operator is used in this example to access individual structure members. The arrow operator can be used only when a pointer to a structure has been created.
/*
*  ptrstc.c
*  C program uses pointers to an array of structures.
*  The Nineveh boat inventory example is used again.
*  Copyright (c) Chris H. Pappas and William H. Murray, 1997
*/

#include <stdio.h>

#define iSTRING15 15
#define iSTRING20 20
#define iNULL_CHAR 1
#define iMAX_BOATS 50
struct stboat {
 char sztype [iSTRING15 + iNULL_CHAR];
 char szmodel[iSTRING15 + iNULL_CHAR];
 char sztitle[iSTRING20 + iNULL_CHAR];
 char szcomment[80];
 int iyear;
 long int lmotor_hours;
 float fretail;
 float fwholesale;
};

int main(void)
{
 int i,iinstock;
 struct stboat astNineveh[iMAX_BOATS],
*pastNineveh;
 pastNineveh=&astNineveh[0];

 printf(“How many boats in inventory? ”);
 scanf(“%d”,&iinstock);
 

   for (i=0; i<iinstock; i++) {
      flushall( );     /
*  flush keyboard buffer */
      printf(“\nPlease enter the make of the boat: ”);
      gets(pastNineveh->sztype);

      printf(“\nPlease enter the model of the boat: ”);
      gets(pastNineveh->szmodel);

      printf(“\nPlease enter the title number for the boat: ”);
      gets(pastNineveh->sztitle);
      printf(
        “\nPlease enter a one line comment about the boat: ”);
      gets(pastNineveh->szcomment);

      printf(“\nPlease enter the model year for the boat: ”);
      scanf(“%d”,&pastNineveh->iyear);

      printf(“\nPlease enter the current hours on ”);
      printf(“the motor for the boat: ”);
      scanf(“%ld”,&pastNineveh->lmotor_hours);

      printf(“\nPlease enter the retail price of the boat: ”);
      scanf(“%f”,&pastNineveh->fretail);

      printf(
         “\nPlease enter the wholesale price of the boat: ”);
      scanf(“%f”,&pastNineveh->fwholesale);
 
      pastNineveh++;
   }

 pastNineveh=&astNineveh[0];
 printf(“\n\n\n”);
 for (i=0; i<iinstock; i++) {
   printf(“A %d %s %s beauty with %ld low hours.\n”,
              pastNineveh->iyear,pastNineveh->sztype,
              pastNineveh->szmodel,pastNineveh->lmotor_hours);
   printf(“%s\n”,pastNineveh->szcomment);
   printf(
      “Grab the deal by asking your Nineveh salesperson for:”);
   printf(“\n#%s ONLY! $%8.2f.\n”,pastNineveh->sztitle,
          pastNineveh->fretail);
          printf(“\n\n”);
          pastNineveh++;
 }

 return (0);
}
The array variable, astNineveh[iMAX_BOATS], and the pointer, *pastNineveh, are associated with the structure by using the following statement:
struct stboat astNineveh[iMAX_BOATS],*pastNineveh;
The address of the array, astNineveh, is copied into the pointer variable, pastNineveh, with the following code:
pastNineveh=&astNineveh[0];
While it is syntactically legal to reference array elements with the syntax that follows, it is not the preferred method:
gets((*pastNineveh).sztype);
Because of operator precedence, the extra parentheses are necessary to prevent the dot (.) member operator from binding before the pointer, *pastNineveh, is dereferenced. It is better to use the arrow operator, which makes the overall operation much cleaner:
gets(pastNineveh->sztype);
While this is not a complex example, it does illustrate the use of the arrow operator. The example also prepares you for the real advantage in using pointers—passing an array of structures to a function.
Passing an Array of Structures to a Function
You learned earlier in the chapter that passing a pointer to a structure could have a speed advantage over simply passing a copy of a structure to a function. This fact becomes more evident when a program makes heavy use of structures. The next program shows how an array of structures can be accessed by a function with the use of a pointer:
/*
*   psastc.c
*   C program shows how a function can access an array
*   of structures with the use of a pointer.
*   The Nineveh boat inventory is used again!
*   Copyright (c) Chris H. Pappas and William H. Murray, 1997
*/

#include <stdio.h>
#define iSTRING15 15
#define iSTRING20 20
#define iNULL_CHAR 1
#define iMAX_BOATS 50

int iinstock;

struct stboat {
 char sztype [iSTRING15 + iNULL_CHAR];
 char szmodel[iSTRING15 + iNULL_CHAR];
 char sztitle[iSTRING20 + iNULL_CHAR];
 char szcomment[80];
 int iyear;
 long int lmotor_hours;
 float fretail;
 float fwholesale;
};

void vprint_data(struct stboat
*stany_boatptr);
int main(void)
{
 int i;
 struct stboat  astNineveh[iMAX_BOATS],
*pastNineveh;
 pastNineveh=&astNineveh[0];

 printf(“How many boats in inventory?\n”);
 scanf(“%d”,&iinstock);

 for (i=0; i<iinstock; i++) {

   flushall( );     /
*  flush keyboard buffer */
   printf(“\nPlease enter the make of the boat: ”);
   gets(pastNineveh->sztype);

   printf(“\nPlease enter the model of the boat: ”);
   gets(pastNineveh->szmodel);

   printf(“\nPlease enter the title number for the boat: ”);
   gets(pastNineveh->sztitle);

   printf(“\nPlease enter a one line comment about the boat: ”);
   gets(pastNineveh->szcomment);
   printf(“\nPlease enter the model year for the boat: ”);
   scanf(“%d”,&pastNineveh->iyear);

   printf(“\nPlease enter the current hours on ”);
   printf(“the motor for the boat: ”);
   scanf(“%ld”,&pastNineveh->lmotor_hours);

   printf(“\nPlease enter the retail price of the boat: ”);
   scanf(“%f”,&pastNineveh->fretail);

   printf(“\nPlease enter the wholesale price of the boat: ”);
   scanf(“%f”,&pastNineveh->fwholesale);

   pastNineveh++;
 }

 pastNineveh=&astNineveh[0];

 vprint_data(pastNineveh);

 return (0);
}
void vprint_data(struct stboat *stany_boatptr)
{
 int i;
 printf(“\n\n\n”);
 for (i=0; i<iinstock; i++) {
   printf(“A %d %s %s beauty with %ld low hours.\n”,
          stany_boatptr->iyear,stany_boatptr->sztype,
          stany_boatptr->szmodel,stany_boatptr->lmotor_hours);
   printf(“%s\n”,stany_boatptr->szcomment);
   printf(
      “Grab the deal by asking your Nineveh salesperson for”);
   printf(“ #%s ONLY! $%8.2f.\n”,stany_boatptr->sztitle,
          stany_boatptr->fretail);
   printf(“\n\n”);
   stany_boatptr++;
 }
}
The first indication that this program will operate differently from the last program comes from the vprint_data( ) function prototype:
void vprint_data(struct stboat *stany_boatptr);
This function expects to receive a pointer to the structure mentioned. In the function, main( ), the array astNineveh[iMAX_BOATS], and the pointer *pastNineveh are associated with the structure with the following code:
struct stboat astNineveh[iMAX_BOATS],*pastNineveh;
Once the information has been collected for Nineveh Boat Sales, it is passed to the vprint_data( ) function by passing the pointer:
vprint_data(pastNineveh);
One major advantage of passing an array of structures to a function using pointers is that the array is now passed call-by-variable or call-by-reference. This means that the function can now access the original array structure, not just a copy. With this calling convention, any change made to the array of structures within the function is global in scope. The output from this program is the same as for the previous examples.
Structure Use in C++
The following C++ program is similar to the previous C program. In terms of syntax, both languages can handle structures in an identical manner. However, the example program takes advantage of C++’s shorthand structure syntax:
//
//  struct.cpp
//  C++ program shows the use of pointers when
//  accessing structure information from a function.
//  Note:  Comment line terminates with a period (.)
//  Copyright (c) Chris H. Pappas and William H. Murray, 1997
//

#include <iostream.h>

#define iSTRING15 15
#define iSTRING20 20
#define iNULL_CHAR 1
#define iMAX_BOATS 50
int iinstock;

struct stboat {
 char sztype [iSTRING15 + iNULL_CHAR];
 char szmodel[iSTRING15 + iNULL_CHAR];
 char sztitle[iSTRING20 + iNULL_CHAR];
 char szcomment[80];
 int iyear;
 long int lmotor_hours;
 float fretail;
 float fwholesale;
};

void vprint_data(stboat *stany_boatptr);

int main(void)
{
 int i;
 char newline;
 stboat astNineveh[iMAX_BOATS],*pastNineveh;
 pastNineveh=&astNineveh[0];
 cout << “How many boats in inventory? ”;
 cin >> iinstock;

 for (i=0; i<iinstock; i++) {
   cout << “\nPlease enter the make of the boat: ”;
   cin >> pastNineveh->sztype;

   cout << “\nPlease enter the model of the boat: ”;
   cin >> pastNineveh->szmodel;

   cout << “\nPlease enter the title number for the boat: ”;
   cin >> pastNineveh->sztitle;

   cout << “\nPlease enter the model year for the boat: ”;
   cin >> pastNineveh->iyear;

   cout << “\nPlease enter the current hours on ”
        << “the motor for the boat: ”;
   cin >> pastNineveh->lmotor_hours;
   cout << “\nPlease enter the retail price of the boat: ”;
   cin >> pastNineveh->fretail;

   cout << “\nPlease enter the wholesale price of the boat: ”;
   cin >> pastNineveh->fwholesale;

   cout << “\nPlease enter a one line comment about the boat: ”;
   cin.get(newline);   // process carriage return
   cin.get(pastNineveh->szcomment,80,’.’);
   cin.get(newline);   // process carriage return

   pastNineveh++;
 }

 pastNineveh=&astNineveh[0];
 vprint_data(pastNineveh);

 return (0);
}

void vprint_data(stboat *stany_boatptr)
{
 int i;
 cout << “\n\n\n”;
 for (i=0; i<iinstock; i++) {
   cout << “A ” << stany_boatptr->iyear << “ ”
        << stany_boatptr->sztype << “ ”
        << stany_boatptr->szmodel << “ beauty with ”
        << stany_boatptr->lmotor_hours << “ low hours.\n”;
   cout << stany_boatptr->szcomment << endl;
   cout << “Grab the deal by asking your Nineveh ”
        << “salesperson for #”;
   cout << stany_boatptr->sztitle << “ONLY! $”
        << stany_boatptr->fretail << “\n\n”;
   stany_boatptr++;
 }
}
One of the real differences between the C++ and C programs is how stream I/O is handled. Usually, simple C++ cout and cin streams can be used to replace the standard C printf( ) and gets( ) functions. For example:
cout << “\nPlease enter the wholesale price of the boat: ”;
cin >> pastNineveh->fwholesale;
One of the program statements requests that the user enter a comment about each boat. The C++ input statement needed to read in the comment line uses a different approach for I/O. Recall that cin will read character information until the first white space. In this case, a space between words in a comment serves as white space. If cin were used, only the first word from the comment line would be saved in the szcomment member of the structure. Instead, a variation of cin is used so that a whole line of text can be entered:
cout << “\nPlease enter a one line comment about the boat: ”;
cin.get(newline);   // process carriage return
cin.get(pastNineveh->szcomment,80,’.’);
cin.get(newline);   // process carriage return
First, cin.get(newline) is used in a manner similar to the flushall( ) function of earlier C programs. In a buffered keyboard system, it is often necessary to strip the newline character from the input buffer. There are, of course, other ways to accomplish this, but they are not more eloquent. The statement cin.get(newline) receives the newline character and saves it in newline. The variable newline is just a collector for the information and is not actually used by the program. The comment line is accepted with the following code:
cin.get(pastNineveh->szcomment,80,’.’);
Here, cin.get( ) uses a pointer to the structure member, followed by the maximum length of the szcomment, 80, followed by a termination character (.). In this case, the comment line will be terminated when (n-1) or 80-1 characters are entered or a period is typed (the n
Additional Manipulations with Structures
There are a few points regarding structures that the previous examples have not illustrated. For example, it is also possible to pass individual structure members to a function. Another property allows the nesting of structures.
Passing Structure Members to a Function
Passing individual structure members is an easy and efficient means of limiting access to structure information within a function. For example, a function might be used to print a list of wholesale boat prices available on the lot. In this case, only the fwholesale price, which is a member of the structure, would be passed to the function. If this is the case, the call to the function would take the form
vprint_price(astNineveh.fwholesale);
In this case, vprint_price( ) is the function name and astNineveh.fwholesale is the structure name and member.
Nesting Structures Within Structures
Structure declarations can be nested. That is, one structure contains a member or members that are structure types. Consider that the following structure could be included in yet another structure:
struct strepair {
 int ioilchange;
 int iplugs;
 int iairfilter;
 int ibarnacle_cleaning;
};
In the main structure, the strepair structure could be included as follows:
struct stboat {
 char sztype [iSTRING15 + iNULL_CHAR];
 char szmodel[iSTRING15 + iNULL_CHAR];
 char sztitle[iSTRING20 + iNULL_CHAR];
 char szcomment[80];
 struct strepair strepair_record;
 int iyear;
 long int lmotor_hours;
 float fretail;
 float fwholesale;
} astNineveh[iMAX_BOATS];
If a particular member from strepair_record is desired, it can be reached by using the following code:
printf(“%d\n”,astNineveh[0].strepair_record.ibarnacle_cleaning);
Structures and Bit-Fields
Both C and C++ give you the ability to access individual bits within a larger data type, such as a byte. This is useful, for example, in altering data masks used for system information and graphics. The capability to access bits is built around the C and C++ structure.
For example, it might be desirable to alter the keyboard status register in a computer. The keyboard status register on a computer contains the following information:
                                   register bits
Keyboard Status:          76543210
Port(417h)
where
bit 0 = right shift depressed (1)
bit 1 = left shift depressed (1)
bit 2 = ctrl depressed (1)
bit 3 = alt depressed (1)
bit 4 = scroll lock active (1)
bit 5 = num lock active (1)
bit 6 = caps lock active (1)
bit 7 = ins active (1)
In order to access and control this data, a structure could be constructed that uses the following form:
struct stkeybits {
 unsigned char
   ucrshift  : 1,       /
* lsb */
   uclshift  : 1,
   ucctrl    : 1,
   ucalt     : 1,
   ucscroll  : 1,
   ucnumlock : 1,
   uccaplock : 1,
   ucinsert  : 1;        /
* msb */
} stkey_register;
The bits are specified in the structure starting with the least significant bit (lsb) and progressing toward the most significant bit (msb). It is feasible to specify more than one bit by just typing the quantity (in place of the 1). Only integer data types can be used for bit-fields.
The members of the bit-field structure are accessed in the normal fashion.

Books24x7.com, Inc 2000 –  


Visual C++ 6(c) The Complete Reference
Visual Studio 6: The Complete Reference
ISBN: B00007FYGA
EAN: N/A
Year: 1998
Pages: 207

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net