开发者

What's the major difference between "union" and "struct" in C.? [duplicate]

开发者 https://www.devze.com 2023-01-21 05:56 出处:网络
This question already has answers here: Closed 12 years ago. Possible Duplicate: Difference between a Structure and a Union in C
This question already has answers here: Closed 12 years ago.

Possible Duplicate:

Difference between a Structure and a Union in C

I could understand what a struct means. But, i am bit confused with the difference between开发者_JAVA技巧 union and struct. Union is like a share of memory. What exactly it means.?


With a union, all members share the same memory. With a struct, they do not share memory, so a different space in memory is allocated to each member of the struct.

For example:

union foo
{
 int x;
 int y;
};

foo f;
f.x = 10;
printf("%d\n", f.y);

Here, we assign the value of 10 to foo::x. Then we output the value of foo::y, which is also 10 since x and y share the same memory. Note that since all members of a union share the same memory, the compiler must allocate enough memory to fit the largest member of the union. So a union containing a char and a long would need enough space to fit the long.

But if we use a struct:

struct foo
{
 int x;
 int y;
};

foo f;
f.x = 10;
f.y = 20;
printf("%d %d\n", f.x, f.y);

We assign 10 to x and 20 to y, and then print them both out. We see that x is 10 and y is 20, because x and y do not share the same memory.

EDIT: Also take note of Gman's comment above. The example I provided with the union is for demonstration purposes only. In practice, you shouldn't write to one data member of a union, and then access another data member. Usually this will simply cause the compiler to interpret the bit pattern as another type, but you may get unexpected results since doing this is undefined behavior.


I've used unions to convert bytes to and from other types. I find it easier than bit-shifting.

union intConverter {
    int intValue;
    struct {
        byte hi;
        byte lo;
    } byteValue;
}

intConverter cv;
cv.intValue =1100;
printf("%X %X\n", cv.byteValue.hi, cv.byteValue.lo);

Where int is 16-bit (was used on a micro controller).


Each member of a union shares the same memory. That means if you change one, you change the others. And if the members are of different types, this can have unpredictable results. (not exactly unpredictable, but hard to predict unless you are aware of the underlying bit patterns that make up the data members).


It may be more useful to have an uncontrived example of what this is good for. (I say "uncontrived" because most bit-banging uses of union are extremely treacherous. Bit-banging unions taken from big-endian to little-endian hardware break in the most (initially) mystifying ways.) (Of course, I've written bit-banging unions to tear apart floating point numbers to implement orders-of-magnitude-faster-than-the-library math functions. I just add assertions about which members are supposed to have the same addresses.)

    struct option1 { int type; /* other members */ };
    struct option2 { int type; /* other members */ };
    struct option3 { int type; /* other members */ };
    union combo {
      int type; // guaranteed to exactly overlap with the structs' ints type.
      struct option1;
      struct option2;
      struct option3;
    };
   // ...
   void foo(union combo *in) {
      switch(in.type) {
        case 1: { struct option1 *bar = in;  //then process an option1 type of request }
        case 2: { struct option2 *bar = in;  //then process an option2 type of request }
        case 3: { struct option3 *bar = in;  //then process an option3 type of request }
      }

This kind of construction is very common in X programming and other situations where one wishes to make a function that can receive many different types of messages (with different argument and layout requirements).


I suppose one way you can think of a union is that it is a set of aliases of varying type to a block of memory where each member of the union is an "alias" with a given type. Each alias refers to the same address in memory. How the bits at that address are interpreted are determined by the alias' type.

The amount of memory the union occupies is always equal to or possibly larger than the largest sized "member" of the union (due to alignment restrictions).


Run this program and find out the output.

#include < stdio.h >

int main()
{
  union _testUnion
  {
    long long x;
    long long y;
  } testUnion;

  struct _testStruct
  {
    long long x;
    long long y;
  }testStruct;
  printf("Sizeof Union %d\n",sizeof(testUnion));
  printf("Sizeof Struct %d\n",sizeof(testStruct));
  return;
}

You will find that the size of struct is double than that of union. This is because union has allocated space for only one variable while struct has allocated for two.


Most answers here are correct. A union is essentially a way to access same data in different ways (For example, you can access/interpret 4 bytes of memory as 1 integers, or as 4 characters). Structs as you know are straightforward - a collection of different, seprate objects with their own memory.

Usually you require Unions at a much later stage in programming as compared to Structs.

0

精彩评论

暂无评论...
验证码 换一张
取 消