Chinaunix首页 | 论坛 | 博客
  • 博客访问: 281223
  • 博文数量: 42
  • 博客积分: 590
  • 博客等级: 中士
  • 技术积分: 447
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-04 01:15
个人简介

健康快乐 虚怀若谷 淡定从容

文章分类

全部博文(42)

分类: C/C++

2011-10-12 14:52:20

From 《C Primer Plus, Fifth Edition》
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. By using an array of unions, 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; };

A structure with a similar declaration would be able to hold an int value and a double value and a char value. This union, however, can hold an int value or a double value or a char value.

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 called save with 10 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 three choices: You can initialize a union to another union of the same type, you can initialize the first element of a union, or, with C99, you can use a designated initializer:


union hold valA;

valA.letter = 'R';

union hold valB = valA; // initialize one union to another

union hold valC = {88}; // initialize digit member of union

union hold valD = {.bigfl = 118.2}; // designated initializer  

Here is how you can use a union:


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. in the next chapter 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 example, 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 could use flits.ownerinfo.owncar.socsecurity, and if flits.status were 1, the program could use flits.ownerinfo.leasecar.name.

graphics/notesicon_icon.gif Summary: Structure and Union Operators

The Membership Operator:

.

General Comments:

This 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, 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  

阅读(2439) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~