Unions: A Quick Look

I l @ ve RuBoard

Unions: A Quick Look

A union is a type that enables you to store different data types in the same memory space (but not simultaneously ). A typical use is a table designed to hold a mixture of types in some order that is neither regular nor known in advance. With a union, you can create an array of equal- sized units, each of which can hold a variety of data types.

Unions are set up in much the same way as structures. There is a union template and a union variable. They can be defined in one step or, by using a union tag, in two. Here is an example of a union template with a tag:

 union hold {     int digit;     double bigfl;     char letter; }; 

Here is an example of defining three union variables of the hold type:

 union hold fit;      /* union variable of hold type       */ union hold save[10]; /* array of 10 union variables        */ union hold * pu;     /* pointer to a variable of hold type */ 

The first declaration creates a single variable fit . The compiler allots enough space so that it can hold the largest of the described possibilities. In this case, the biggest possibility listed is double , which requires 64 bits, or 8 bytes, on our system. The second declaration creates an array save with ten elements, each 8 bytes in size . The third declaration creates a pointer that can hold the address of a hold union.

You can initialize a union. Because the union holds only one value, the rules are different from those in a structure. In particular, you have two choices: You can initialize a union to another union of the same type, or you can initialize the first element of a union:

 union hold valA; valA.letter = 'R'; union hold valB = valA;  /* initialize one union to another  */ union hold valC = {88};  /* initialize digit member of union */ 

You can use the -> operator with pointers to unions in the same fashion that you use the operator with pointers to structures:

 pu = &fit; x = pu->digit;  /* same as x = fit.digit */ 

Here is how a union is used:

 fit.digit = 23;   /* 23 is stored in fit; 2 bytes used   */ fit.bigfl = 2.0;  /* 23 cleared, 2.0 stored; 8 bytes used */ fit.letter = 'h'; /* 2.0 cleared, h stored; 1 byte used   */ 

The dot operator shows which data type is being used. Only one value is stored at a time. You can't store a char and an int at the same time, even though there is enough space to do so. It is your responsibility to keep track of the data type currently being stored in a union.

You can use the -> operator with pointers to unions in the same fashion that you use the operator with pointers to structures:

 pu = &fit; x = pu->digit;  /* same as x = fit.digit */ 

The next sequence shows what not to do:

 fit.letter = 'A'; flnum = 3.02*fit.bigfl;   /* ERROR ERROR ERROR */ 

This sequence is wrong because a char type is stored, but the next line assumes that the content of fit is a double type.

However, sometimes it can be useful to use one member to place values into a union and to then use a different member for viewing the contents. Listing 15.4 in the next chapter "Bit Fiddling," shows an example.

Another place you might use a union is in a structure for which the stored information depends on one of the members . For instance, suppose you have a structure representing an automobile. If the automobile is owned by the user , you want a structure member describing the owner. If the automobile is leased, you want the member to describe the leasing company. Then you can do something along the following lines:

 struct owner {      char socsecurity[12];      ... }; struct leasecompany  {      char name[40];      char headquarters[40];      ... } union data {      struct owner owncar;      struct leasecompany leasecar; }; struct car_data {      char make[15];      int status; /* 0 = owned, 1 = leased */      union data ownerinfo;      ... }; 

Suppose flits is a car_data structure. Then if flits.status were 0, the program would use flits.status.ownerinfo.owncar , and if flits.status were 1, the program would use flits.status.ownerinfo.leasecar .

Summary: Structure and Union Operators

The Membership Operator:

 . 

General Comments:

The . operator is used with a structure or union name to specify a member of that structure or union. If name is the name of a structure and member is a member specified by the structure template, then the following identifies that member of the structure:

 name.member 

The type of name.member is the type specified for member . The membership operator can also be used in the same fashion with unions.

Example:

 struct {        int code;        float cost; } item; item.code = 1265; 

The last statement assigns a value to the code member of the structure item .

The Indirect Membership Operator:

 -> 

General Comments:

This operator is used with a pointer to a structure or union to identify a member of that structure or union. Suppose that ptrstr is a pointer to a structure and that member is a member specified by the structure template. Then the statement

 ptrstr->member 

identifies that member of the pointed-to structure. The indirect membership operator can be used in the same fashion with unions.

Example:

 struct {        int code;        float cost; } item, * ptrst; ptrst = &item; ptrst->code = 3451; 

The last statement assigns an int value to the code member of item . The following three expressions are equivalent:

 ptrst->code   item.code    (*ptrst).code 
I l @ ve RuBoard


C++ Primer Plus
C Primer Plus (5th Edition)
ISBN: 0672326965
EAN: 2147483647
Year: 2000
Pages: 314
Authors: Stephen Prata

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