Re: Unions and Structure Questions
From: Barry Schwarz (schwarzb_at_deloz.net)
Date: 01/18/04
- Next message: Barry Schwarz: "Re: Question about TSR Programs"
- Previous message: Barry Schwarz: "Re: Unions and Structure Questions"
- In reply to: Anthony Borla: "Re: Unions and Structure Questions"
- Next in thread: B. v Ingen Schenau: "Re: Unions and Structure Questions"
- Reply: B. v Ingen Schenau: "Re: Unions and Structure Questions"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: 17 Jan 2004 23:07:52 GMT
On Sat, 17 Jan 2004 09:41:03 GMT, "Anthony Borla"
<ajborla@bigpond.com> wrote:
>"kazack" <gadgetsnsuch@talon.net> wrote in message
>news:wV4Ob.10103$Bv6.3065412@news1.epix.net...
>>
>> A union is the same as a structure with the exception that a
>> union can only use one item where a structure can use all?
>>
>> Example:
>>
>> int account
>> string fname
>> string lname
>> string phone
>>
>> A structure uses all of the above where a union can only use
>> one of the above at a time?
>>
>> If I am wrong please correct me, also why would one want to
>> use a union over a structure and is it actually pratical to do so?
>>
>
>Whereas the members of a struct each occupy a different memory location, the
>members of a union each occupy the *same* memory location. For example, this
>struct:
>
> struct Product
> {
> long productCode;
> float cost;
> };
>
>occupies:
>
> sizeof(long) + sizeof(float) bytes
Plus the size of any padding between the members and after the last
member.
>
>whereas this union:
>
> union Product
> {
> long productCode;
> float cost;
> };
>
>occupies:
>
> sizeof(long) > sizeof(float) ? sizeof(long) : sizeof(float) bytes
Plus any padding.
>
>or, the amount it takes to store the larger of the two types [but *not* both
>at the same time].
>
>Therefore, a struct is used to group data together so that it may be easily
>accessed, manipulated or stored [i.e. think of geograpical address
>information - it is handled as a single entity but consists of several
>sub-entities such as street name, state and zip code].
>
>On the other hand, a union serves more specialist needs, allowing:
>
>* The same memory area to reused [useful in environments
> where there are memory constraints e.g. embedded systems]
>
>* The contents in the same memory area to be interpreted
> differently [i.e. the same location holds different data at
> different times] to facilitate data handling
>
>An example of the latter is the use of a buffer used to read variant binary
>data from a file.
>
>At any one moment a single, fixed-size chunk of data [i.e. a data 'record']
>is read from the file, but, depending on the value of the first byte of each
>'record', the contained data is to be interpreted differently. Assume these
>are the data types of each 'record':
>
> struct RType_A { ... };
> struct RType_B { ... };
>
>Now, we can define a struct as follows:
>
> struct DataRecord
> {
> char recordType;
> char data[RECSIZE];
> };
>
>and separately declare these variables:
>
> DataRecord record;
> RType_A ra;
> RType_B rb;
>
>We read data as follows:
>
> ...
> fread(&record, sizeof(DataRecord), 1, stream);
> ...
>
>check the 'record' type, then move the data to the relevant record variable:
>
> ...
> if (record.recordType == TYPE_A)
> ...
> // Move from 'record.data' to 'ra' for processing
> ...
> else if (record.recordType == TYPE_B)
> ...
> // Move from 'record.data' to 'rb' for processing
> ...
> ...
>
>and can then perform any required data processing.
>
>If, instead, we use a union to describe the variant data:
>
> struct DataRecord
> {
> char recordType;
> union Data
> {
> struct RType_A ra;
> struct RType_B rb;
> } data;
> };
>
>we need only declare:
>
> DataRecord record;
>
>and read data as before:
>
> ...
> fread(&record, sizeof(DataRecord), 1, stream);
> ...
>
>However, this time, no data movement need take place - the data is already
>in memory in the exact format required for processing. All that is needed is
>a check to see what type of data is currently stored:
>
> ...
> if (record.recordType == TYPE_A)
> ...
> // Process 'record.data' for TYPE_A
> ...
> else if (record.recordType == TYPE_B)
> ...
> // Process 'record.data' for TYPE_B
> ...
> ...
>
>and it can immediately be processed. Simply by using union, memory has been
>saved, and data movement avoided.
>
I hope one of the experts weighs in with an opinion on whether the
approach you describe gets around the limitation in the new C99
standard that prohibits accessing one member of a union when the data
was stored in a different member. Since you did not refer to any
particular member of the union, we could say you loaded the union
anonymously.
<<Remove the del for email>>
- Next message: Barry Schwarz: "Re: Question about TSR Programs"
- Previous message: Barry Schwarz: "Re: Unions and Structure Questions"
- In reply to: Anthony Borla: "Re: Unions and Structure Questions"
- Next in thread: B. v Ingen Schenau: "Re: Unions and Structure Questions"
- Reply: B. v Ingen Schenau: "Re: Unions and Structure Questions"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|
|