C: union 实际用在什么地方?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1951269/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C: Where is union practically used?
提问by yesraaj
I have a example with me where in which the alignment of a type is guaranteed, union max_align . I am looking for a even simpler example in which union is used practically, to explain my friend.
我有一个例子,其中保证了类型的对齐, union max_align 。我正在寻找一个更简单的例子来解释我的朋友。
回答by Yousf
I usually use unions when parsing text. I use something like this:
我通常在解析文本时使用联合。我使用这样的东西:
typedef enum DataType { INTEGER, FLOAT_POINT, STRING } DataType ;
typedef union DataValue
{
int v_int;
float v_float;
char* v_string;
}DataValue;
typedef struct DataNode
{
DataType type;
DataValue value;
}DataNode;
void myfunct()
{
long long temp;
DataNode inputData;
inputData.type= read_some_input(&temp);
switch(inputData.type)
{
case INTEGER: inputData.value.v_int = (int)temp; break;
case FLOAT_POINT: inputData.value.v_float = (float)temp; break;
case STRING: inputData.value.v_string = (char*)temp; break;
}
}
void printDataNode(DataNode* ptr)
{
printf("I am a ");
switch(ptr->type){
case INTEGER: printf("Integer with value %d", ptr->value.v_int); break;
case FLOAT_POINT: printf("Float with value %f", ptr->value.v_float); break;
case STRING: printf("String with value %s", ptr->value.v_string); break;
}
}
If you want to see how unions are used HEAVILY, check any code using flex/bison. For example see splint, it contains TONS of unions.
回答by zebrabox
I've typically used unions where you want to have different views of the data e.g. a 32-bit colour value where you want both the 32-bit val and the red,green,blue and alpha components
我通常在您想要对数据有不同视图的地方使用联合,例如 32 位颜色值,您需要 32 位 val 和红色、绿色、蓝色和 alpha 分量
struct rgba
{
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
};
union
{
unsigned int val;
rgba components;
}colorval32;
NB You could also achieve the same thing with bit-masking and shifting i.e
注意你也可以通过位掩码和移位实现同样的事情,即
#define GETR(val) ((val&0xFF000000) >> 24)
but I find the union approach more elegant
但我发现联合方法更优雅
回答by wrapperm
For accessing registers or I/O ports bytewise as well as bitwise by mapping that particular port to memory, see the example below:
要通过将特定端口映射到内存来按字节和按位访问寄存器或 I/O 端口,请参见以下示例:
typedef Union
{
unsigned int a;
struct {
unsigned bit0 : 1,
bit1 : 1,
bit2 : 1,
bit3 : 1,
bit4 : 1,
bit5 : 1,
bit6 : 1,
bit7 : 1,
bit8 : 1,
bit9 : 1,
bit10 : 1,
bit11 : 1,
bit12 : 1,
bit13 : 1,
bit14 : 1,
bit15 : 1
} bits;
} IOREG;
# define PORTA (*(IOREG *) 0x3B)
...
unsigned int i = PORTA.a;//read bytewise
int j = PORTA.bits.bit0;//read bitwise
...
PORTA.bits.bit0 = 1;//write operation
回答by Nate Kohl
In the Windows world, unions
are commonly used to implement tagged variants, which are (or were, before .NET?) one standard way of passing data between COM objects.
在 Windows 世界中,unions
通常用于实现标记变体,它们是(或在 .NET 之前?)在COM 对象之间传递数据的一种标准方式。
The idea is that a union
type can provide a single natural interface for passing arbitrary data between two objects. Some COM object could pass you a variant (e.g. type VARIANT
or _variant_t
) which could contain either a double
, float
, int
, or whatever.
这个想法是一个union
类型可以提供一个单一的自然接口,用于在两个对象之间传递任意数据。某些COM对象可以传给你一个变种(如类型VARIANT
或_variant_t
)可能包含一个double
,float
,int
,或什么的。
If you have to deal with COM objects in Windows C++ code, you'll see variant types all over the place.
如果您必须在 Windows C++ 代码中处理 COM 对象,您会看到到处都是变体类型。
回答by Bastien Léonard
SDL uses an union for representing events: http://www.libsdl.org/cgi/docwiki.cgi/SDL_Event.
SDL 使用联合来表示事件:http: //www.libsdl.org/cgi/docwiki.cgi/SDL_Event。
回答by Makis
Unions are useful if you have different kinds of messages, in which case you don't have to know in any intermediate levels the exact type. Only the sender and receiver need to parse the message actual message. Any other levels only really need to know the size and possibly sender and/or receiver info.
如果您有不同类型的消息,联合很有用,在这种情况下,您不必在任何中间级别知道确切的类型。只有发送方和接收方需要解析消息实际消息。任何其他级别只需要知道大小以及可能的发送者和/或接收者信息。
回答by ironic
struct cat_info
{
int legs;
int tailLen;
};
struct fish_info
{
bool hasSpikes;
};
union
{
fish_info fish;
cat_info cat;
} animal_data;
struct animal
{
char* name;
int animal_type;
animal_data data;
};
回答by ironic
do you mean something like this ?
你的意思是这样吗?
union {
long long a;
unsigned char b[sizeof(long long)];
} long_long_to_single_bytes;
ADDED:
添加:
I have recently used this on our AIX machine to transform the 64bit machine-indentifier into a byte-array.
我最近在我们的 AIX 机器上使用它来将 64 位机器标识符转换为字节数组。
std::string getHardwareUUID(void) {
#ifdef AIX
struct xutsname m; // aix specific struct to hold the 64bit machine id
unamex(&b); // aix specific call to get the 64bit machine id
long_long_to_single_bytes.a = m.longnid;
return convertToHexString(long_long_to_single_bytes.b, sizeof(long long));
#else // Windows or Linux or Solaris or ...
... get a 6byte ethernet MAC address somehow and put it into mac_buf
return convertToHexString(mac_buf, 6);
#endif
回答by Khelben
I've used sometimes unions this way
我有时用这种方式使用工会
//Define type of structure
typedef enum { ANALOG, BOOLEAN, UNKNOWN } typeValue_t;
//Define the union
typedef struct {
typeValue_t typeValue;
/*On this structure you will access the correct type of
data according to its type*/
union {
float ParamAnalog;
char ParamBool;
};
} Value_t;
Then you could declare arrays of different kind of values, storing more or less efficiently the data, and make some "polimorph" operations like:
然后你可以声明不同类型值的数组,或多或少地有效地存储数据,并进行一些“polimorph”操作,例如:
void printValue ( Value_t value ) {
switch (value.typeValue) {
case BOOL:
printf("Bolean: %c\n", value.ParamBool?'T':'F');
break;
case ANALOG:
printf("Analog: %f\n", value.ParamAnalog);
break;
case UNKNOWN:
printf("Error, value UNKNOWN\n");
break;
}
}
回答by Khelben
Here is another example where a union could be useful.
这是联合可能有用的另一个示例。
(not my own idea, I have found this on a document discussing c++ optimizations)
(不是我自己的想法,我在讨论C++ 优化的文档中找到了这个 )
begin-quote
开始报价
.... Unions can also be used to save space, e.g.
.... 也可以使用联合来节省空间,例如
first the non-union approach:
首先是非工会方法:
void F3(bool useInt) {
if (y) {
int a[1000];
F1(a); // call a function which expects an array of int as parameter
}
else {
float b[1000];
F2(b); // call a function which expects an array of float as parameter
}
}
Here it is possible to use the same memory area for a and b because their live ranges do not overlap. You can save a lot of cpu-cache spaceby joining a and b in a union:
这里可以为 a 和 b 使用相同的内存区域,因为它们的生存范围不重叠。您可以通过将 a 和 b 加入联合来节省大量cpu-cache 空间:
void F3(bool useInt) {
union {
int a[1000];
float b[1000];
};
if (y) {
F1(a); // call a function which expects an array of int as parameter
}
else {
F2(b); // call a function which expects an array of float as parameter
}
}
Using a union is not a safe programming practice, of course, because you will get no warning from the compiler if the uses of a and b overlap. You should use this method only for big objects that take a lot of cache space. ...
当然,使用联合并不是一种安全的编程实践,因为如果 a 和 b 的使用重叠,您将不会收到编译器的警告。您应该仅对占用大量缓存空间的大对象使用此方法。...
end-qoute
结束报价