1. We have moved from vBulletin to XenForo and you are viewing the site in the middle of the move. Though the functional aspect of everything is working fine, we are still working on other changes including the new design on Xenforo.
    Dismiss Notice

Unions in C : A less used but a powerful feature of C

Discussion in 'C' started by Amit Ray, Jul 20, 2004.

  1. WHAT IS A UNION

    A union, is a collection of variables of different types, just like a structure. However, with unions, you can only store information in one field at any one time.

    You can picture a union as like a chunk of memory that is used to store variables of different types. Once a new value is assigned to a field, the existing data is wiped over with the new data.

    A union can also be viewed as a variable type that can contain many different variables (like a structure), but only actually holds one of them at a time (not like a structure). This can save memory if you have a group of data where only one of the types is used at a time. The size of a union is equal to the size of it's largest data member. In other words, the C compiler allocates just enough space for the largest member. This is because only one member can be used at a time, so the size of the largest, is the most you will need. Here is an example:

    ...
    union time
    {
    long simpleDate;
    double perciseDate;​
    }mytime;
    ....

    The union above could be used to either store the current time (in seconds) to hold time accurate to a second. Or it could be used to hold time accurate to a millisecond. Presumably there are times when you would want one or the other, but not both. This declaration should look familiar. It is the same as a struct definition, but with the keyword union instead of struct.

    ACCESSING UNION FIELDS

    To access the fields of a union, use the dot operator(.) just as you would for a structure. When a value is assigned to one member, the other member(s) get whipped out since they share the same memory. Using the example above, the precise time can be accessed like this:

    . . .
    printTime( mytime.perciseDate );
    . . .


    In larger programs it may be difficult to keep track of which field is the currently used field. This is usually handled by using another variable to keep track of that. For example, you might use an integer called mode. When mode equals one, the regular date (simpleDate) is used. If mode is two, then perciseDate is used. This mode variable needs to be set every time a different member in the union is used. Here is a sample program to illustrate the use of unions.

    #include <stdio.h>

    int main()
    {
    union data
    {
    char a;
    int x;
    float f;​
    } myData;

    int mode = 1;

    myData.a = 'A';
    printf("Here is the Data:\n%c\n%i\n%.3f\n", myData.a, myData.x, myData.f );

    myData.x = 42;
    mode = 2;
    printf("Here is the Data:\n%c\n%i\n%.3f\n", myData.a, myData.x, myData.f );

    myData.f = 101.357;
    mode = 3;
    printf("Here is the Data:\n%c\n%i\n%.3f\n", myData.a, myData.x, myData.f );

    if( mode == 1 )
    printf("The char is being used\n");​
    else if( mode == 2 )
    printf("The int is being used\n");​
    else if( mode == 3 )
    printf("The float is being used\n");​

    return 0;​
    }

    This little program declares a union with an int, float, and char. It uses each field, and after each use prints out all the fields (with one ugly printf statement). Here is some sample output:

    Here is the Data:
    A
    577
    0.000
    Here is the Data:
    *
    42
    0.000
    Here is the Data:

    1120581321
    101.357
    The float is being used

    Your output might be different. Clearly the data in the unused fields is just garbage. This happens because different types are treated differently by the computer. So if one type is set, the memory is not going to be in the format of the other types. Also mode is used to keep track of the type. In this program it is pretty useless, but in larger programs it would be a great help in keeping track of the unions use.


    Summary

    Union allows same storage to be referenced in different ways

    Only one way is valid at any given time

    Usage
    • access individual bytes of larger type
    • variable format input records (coded records)
    • sharing an area to save storage usage
    • unions not used nearly as much as structures

    Example

    union HAH
    {
    int igor;
    char chuck;
    float felix;​
    };
    ...
    union HAH Jody;
    ...


    Jody.igor = 2175; /* felix and chuck not valid */
    Jody.chuck = 'X'; /* igor and felix not valid */
    Jody.felix = 2.5; /* igor and chuck not valid */

    t = Jody.igor;


    • sizeof union is size of its biggest member

    • Unions most often contain different types of structures

    • Can only initialize first member of union

    • Can assign (copy) one union variable to another

    • Can pass union or pointer to union as function arg

    • Function can return union type

    • Can define pointers to union type object

    • Members accessed as unionvar.member or unionptr-$gt;member

    • Syntax, format and use of tags and declarators like struct, but members overlay each other, rather than following each other in memory

    union HAH
    {
    short svar;
    long lvar;
    char cvar;
    long double dvar;​
    };


    [​IMG]

    Thus we see Unions are declared in the same fashion as structs, but have a fundamental difference. Only one item within the union can be used at any time, because the memory allocated for each item inside the union is in a shared memory location.

    struct conditions
    {
    float temp;
    union feels_like
    {
    float wind_chill;
    float heat_index;​
    }​
    } today;


    As you know, wind_chill is only calculated when it is "cold" and heat_index when it is "hot". There is no need for both. So when you specify the temp in today, feels_like only has one value, either a float for wind_chill or a float for heat_index.

    Types inside of unions are unrestricted, you can even use structs within unions.

    Other Resources :

    http://www.iota-six.co.uk/c/h5_unions.asp
    http://www.sysprog.net/cunions.html
    http://publications.gbdirect.co.uk/c_book/chapter6/unions.html
    http://www.cs.cf.ac.uk/Dave/C/node9.html#SECTION00920000000000000000

    Amit Ray. :)

    The trouble with programmers is that you can never tell what a programmer is doing until it's too late. (Seymour Cray) :rolleyes:
     
    shabbir and theMachineUser like this.
  2. asadullah.ansari

    asadullah.ansari TechCake

    Who is saying..It's uses is less. In all Embedded Products and telecom(semicon) union is used broadly!!!
     
  3. debleena_doll2002

    debleena_doll2002 New Member

    Except it (Telecom,semicin etc) , other software for finance,stattistical software also should use this preety nice feature.
     
  4. nileshkumar_1982

    nileshkumar_1982 New Member

    By using union , we can make optimized code. when we are goin to code then we should remember in mind " Union also a featute" . According to that we should write code.
     
  5. crazytolearn57

    crazytolearn57 New Member

    i agree
     
  6. bashamsc

    bashamsc New Member

    Good information
     
  7. aisha.ansari84

    aisha.ansari84 New Member

    unions are powerful,but one should know the proper place to use it
     
  8. iamanexpert

    iamanexpert New Member

    i learned a lot from this article
     
  9. Manojbijnori

    Manojbijnori New Member

    This is really good but which one is better union or structure
     
  10. Tobiasgar

    Tobiasgar New Member

    The select queries that you combine in a union query must have the same number of output fields, in the same order, and with the same or compatible data types. When you run a union query, data from each set of corresponding fields is combined into one output field, so that the query output has the same number of fields as each of the select statements.:crazy:
     
  11. Nicolas

    Nicolas New Member

    The first example is fairly bad.
    When you use 'A' to initialize the char you leave the 3 other bytes uninitialized... Generating this random 577...

    If you start by initializing x at 0 you set the 4 bytes of the union to 0.
    Then the value of x after setting a to 'A' will give you 65. The result makes complete sense 65 being the ASCII value of the char 'A'.
     
  12. Scripting

    Scripting John Hoder

    This is really very good article! Well explained and it may be very useful to use unions :)
     
  13. IkarusDowned

    IkarusDowned New Member

    excellent post!
    one thing:

    it should be noted that for those using C++ and unions, this is not 100% true.
    Unions are restricted to primative types, along with any type that has implicit constructors / destructors. For example:

    Code:
    struct A {
         int value;
    };
     
    struct B {
        int value;
       B() :value(100) {}
    };
     
    union AB {
        A a;
        B b;   //no good
    };
    
    At least in GCC, the above will throw a compilation exception.
    You can, of course, use POINTERS to arbitarary types, since pointers are primatives.
     
    shabbir likes this.

Share This Page