C:联合实际使用在哪里?

yes*_*aaj 30 c c++ unions

我有一个例子,我保证了类型的对齐,union max_align.我正在寻找一个更简单的例子,其中实际上使用了union来解释我的朋友.

You*_*usf 33

我通常在解析文本时使用联合.我使用这样的东西:

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;
   }
}
Run Code Online (Sandbox Code Playgroud)

如果你想看看HEAVILY如何使用联合,请使用flex/bison检查任何代码.例如,见splint,它包含TONS of union.


zeb*_*box 6

我通常使用你想要拥有不同数据视图的联合,例如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;
Run Code Online (Sandbox Code Playgroud)

NB您也可以通过位屏蔽和移位来实现相同的功能

#define GETR(val) ((val&0xFF000000) >> 24)
Run Code Online (Sandbox Code Playgroud)

但我觉得工会的态度更优雅

  • 请注意(标准)C不支持这一点 - 分配给一个联合中的一个成员然后从另一个成员读取是未定义的行为.编译器/系统实现通常以他们自己的特定方式支持这一点. (7认同)
  • 但是`struct rgba`可能有填充,即使没有填充,`sizeof(unsigned int)`可能也可能不等于`sizeof(struct rgba)`(4表示没有填充).即,你可能不想这样做. (2认同)
  • @Alok:更不用说`struct`将依次有`r`,`g`,`b`和`a`(有或没有填充),而`unsigned int`字节顺序将依赖于endianness .换句话说,此代码不可移植,并且在另一个处理器上进行编译时可能会以奇怪的方式失败. (2认同)

wra*_*erm 5

要通过将特定端口映射到内存来按字节顺序访问寄存器或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
Run Code Online (Sandbox Code Playgroud)

  • 根据C标准:"单元内的位域分配顺序(高位到低位或低位到高位)是实现定义的.可寻址存储单元的对齐是未指定的." (8认同)
  • 如果您必须处理大/小端序转换,请不要使用此方法 (6认同)