2011-08-26 44 views
10

最近我在windows上工作,我发现很多数据结构被定义为structunion作为成员变量。 Windows的例子是EVT_VARIANT什么是工会?

我不明白这背后的目的是什么。

+0

嗯,究竟是什么导致了你的问题?工会的目的是分时间分享一个内存区域,即在同一个内存区域的不同时间存储不同类型的数据,这可以在任何地方工作,即一个联合可以被自己使用,或者它可以被用作一个结构的成员。或者在一个结构中使用union的奇怪,因此,不清楚你为什么要问这个问题 – AnT

回答

16

struct包含union成员时,它通常用作节省空间的机制。如果struct可以是只有某些成员有效的某些子类型,那么union是不浪费空间的好方法。

例如

enum NumberKind { 
    Integer, 
    FloatingPoint 
}; 

struct Number { 
    NumberKind kind; 
    union { 
    int integerValue; 
    float floatValue; 
    }; 
}; 

在这种情况下我已经定义了一个struct号码可以具有类型类型数值:浮点和整数。同时拥有这两个存储是不合理的,而不是浪费空间,因为我创建了一个union,这使得两个存储的大小相等。根据要求

的上面的示例使用

void PrintNumber(Number value) { 
    if (value.kind == Integer) { 
    printf("%d\n", value.integerValue); 
    } else { 
    printf("%f\n", value.floatValue); 
    } 
} 
+1

@downvoter,谨慎解释一下? – JaredPar

+0

感谢你的解释,但是请你详细说明一下它的用法。 – Avinash

+1

@Avinash增加了一个样本用例 – JaredPar

1

当您需要变体式结构时,通常使用结构技术中的联合。它通常伴随着一个类型标识符,用于确定要检查的工会中的哪个项目。它也可以用相反的方式看出来,例如在* NIX上的Xlib中,它是一个与结构体的联合,第一个成员在所有结构体之间相同,从而定义哪个结构体具有您需要的数据。

0

工会意味着你可以有它的成员为可能值之一。 在以下示例中,您会看到每个值的值。 但是这个联合可以是一些其他结构的成员,它只需指定一个值 - 浮动或不是两个整数。 希望这有助于。

union { 
      float u_f; 
      int u_i; 
    }var; 

    var.u_f = 23.5; 
    printf("value is %f\n", var.u_f); 
    var.u_i = 5; 
    printf("value is %d\n", var.u_i) 
3

想象一下,你有一个存放一个数据包的结构体。数据包中的数据可以是几种不同的类型,因此您将该类型存储在名为type的成员中。因此,要读取此数据包中的数据,首先检查类型,然后读取相应的数据成员,数据成员应包含数据包中的数据。

如果没有工会的数据结构是这样的:

struct data { 
    type_t type; 

    int number; 
    char * string; 
    double fraction; 
    long long big_number; 
} 

这将是一个相当大的数据结构。它使用足够的空间来存储每种可能的数据类型之一。如果您在任何时间点肯定只有其中一位包含有用信息的成员,那就没有必要了。

如果我们使用工会:

struct data { 
    type_t type; 

    union payload { 
     int number; 
     char * string; 
     double fraction; 
     long long big_number; 
    } 
} 

然后该结构包含足够的空间来存储型加载荷成员之一(即你将分配的内存等于type_t大小的量加最大可能的有效载荷成员的大小)。这节省了空间的负担并且更有效率。

但是你必须小心,因为如果有效载荷包含一个int,你仍然可以读取它作为double。当你的程序试图错误地解释数据时,你可能会得到非常奇怪的数字

3

作为64KB内存相当多的日子的遗留物,你在C++中有一个工具,允许多个变量共享相同的记忆(但显然,不是在同一时间)。这就是所谓的联盟,并有四种基本方法,使您可以使用一个:

  • ,这样一个变量A在一个点在一个程序中,这就是后来占据的内存块,你可以用它被不同类型的另一个变量B占用,因为不再需要A.我建议你不要这样做。这种安排隐含着错误的风险是不值得的。您可以通过动态分配内存来实现相同的效果。

  • 或者,您可能会遇到需要大量数据的程序,但您在执行之前不知道数据类型是什么 - 它将由输入数据决定。我也建议你不要在这种情况下使用的工会,因为你可以使用几个不同的类型,并再次的指针达到同样的效果,动态分配内存。

  • 第三种可能的联合使用方式是您可能需要重复使用的一种方式 - 当您想要以两种或多种不同方式解释相同数据时。当你有一个long类型的变量时,可能会发生这种情况,并且您想将它作为short类型的两个值处理。 Windows有时会在传递给函数的long类型的单个参数中封装两个short值。当你想把一个包含数字数据的内存块当作一串字节来处理时,就会出现另一个实例,只是为了移动它。

  • 可以使用工会作为传递对象或围绕你不事先知道它的类型将是其中一个数据值的方法。工会可以提供存储您可能具有的任何一种可能的类型。

如果你认为我是一个天才,解释什么是工会和它的一些可能的应用程序,我不能赞扬这一点。 (:这个信息来自Ivor Horton的Beginning Visual C++ 2010,我碰巧坐在了我的桌子上,我希望这有助于我的工作