C++ C:实际上在哪里使用union?

C++ C:实际上在哪里使用union?,c++,c,unions,C++,C,Unions,我有一个例子,其中一个类型的对齐是有保证的,union max_align。我想找一个更简单的例子来解释我的朋友,在这个例子中,工会被实际使用 你的意思是这样的吗 union { long long a; unsigned char b[sizeof(long long)]; } long_long_to_single_bytes; 添加了: 我最近在AIX机器上使用它将64位机器标识符转换为字节数组 std::string getHardwareUUID(void) { #ifd

我有一个例子,其中一个类型的对齐是有保证的,union max_align。我想找一个更简单的例子来解释我的朋友,在这个例子中,工会被实际使用

你的意思是这样的吗

union {
   long long a;
   unsigned char b[sizeof(long long)];
} long_long_to_single_bytes;
添加了

我最近在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
例如:


当使用不同的套接字类型时,但您希望引用一个comon类型。

另一个示例更多:保存正在进行的转换

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;
};
typedef union {
  long int_v;
  float float_v;
} int_float;

void foo(float v) {
  int_float i;
  i.float_v = v;
  printf("sign=%d exp=%d fraction=%d", (i.int_v>>31)&1, ((i.int_v>>22)&0xff)-128, i.int_v&((1<<22)-1));
}
typedef联合{
长国际;
浮球浮球;
}国际浮点数;
无效foo(浮动v){
国际浮点数i;
i、 浮点数v=v;

printf(“符号=%d exp=%d分数=%d”,(i.int\u v>>31)和1、((i.int\u v>>22)和0xff)-128、i.int\u v&((131)和1、((i>>22)和0xff)-128、i&((1我在解析文本时通常使用联合体。我使用类似的方法:

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;
   }
}

如果您想了解联合是如何大量使用的,请使用/检查任何代码。例如,请参阅,它包含大量联合。

要通过将特定端口映射到内存来访问寄存器或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

我通常使用联合,您希望对数据有不同的视图 e、 g.32位颜色值,其中需要32位val和红、绿、蓝和阿尔法分量

struct rgba
{
  unsigned char r;
  unsigned char g;
  unsigned char b;
  unsigned char a;
};

union  
{
  unsigned int val;
  rgba components;
}colorval32;
注意,您也可以通过位掩蔽和移位实现相同的功能,即

#define GETR(val) ((val&0xFF000000) >> 24)

但是我发现union方法更优雅

为了方便起见,我使用union让我使用同一个类来存储xyzw和rgba值

#ifndef VERTEX4DH
    #define VERTEX4DH

    struct Vertex4d{

        union {
            double x;
            double r;
        };
        union {
            double y;
            double g;
        };
        union {
            double z;
            double b;
        };
        union {
            double w;
            double a;
        };

        Vertex4d(double x=0, double y=0,double z=0,double w=0) : x(x), y(y),z(z),w(w){}
    };

#endif

如果您有不同类型的消息,则联合非常有用,在这种情况下,您不必知道任何中间级别的确切类型。只有发送者和接收者需要解析消息的实际消息。任何其他级别只需要知道消息的大小以及可能的发送者和/或接收者信息。

可以找到许多联合的示例在
中。在某些IP堆栈中(例如在BSD
中)很少有其他IP堆栈


作为一般规则,协议实现使用联合构造。

我有时会以这种方式使用联合

//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;
然后,您可以声明不同类型值的数组,或多或少高效地存储数据,并执行一些“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;
    }
 }

这是另一个工会可能有用的例子

(这不是我自己的想法,我在一份文件上找到了这个。) )

开始报价

..接头也可用于节省空间,例如

第一,非工会办法:

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
    }
}
在这里,可以对a和b使用相同的内存区域,因为它们的活动范围是相同的 不重叠。通过将a和b合并,可以节省大量cpu缓存空间

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
    }
}
当然,使用联合不是一种安全的编程实践,因为您不会得到任何好处 如果a和b的使用重叠,编译器将发出警告。您应仅使用此方法 对于占用大量缓存空间的大型对象


end qoute

当在某些地方(例如一些算法技术)需要时,联合也会很有用。

在Windows世界中,
联合通常用于实现,它是(或曾经是.NET之前的?)之间传递数据的一种标准方式

其思想是,
联合
类型可以提供一个单一的自然接口,用于在两个对象之间传递任意数据。某些COM对象可以向您传递一个变量(例如,类型或),该变量可以包含一个
双精度
浮点
整数
,或其他变量

如果你必须处理Windows C++代码中的COM对象,你会看到所有地方都有不同的类型。

      • 读取需要强制转换为特定类型的序列化数据时
      • 将语义值从
        lex
        返回到
        yacc
        yylval
      • 实现多态类型时,尤其是读取DSL或通用语言的多态类型
      • 当实现一个调度器时,该调度器专门调用打算采用不同类型的函数

      最近,我想我看到了一些在中使用的联合。向量编程在中使用,GPU硬件和其他

      向量可能对应于128位寄存器。它在体系结构中非常常用。由于硬件有128位寄存器,您可以在寄存器/变量中存储4个单精度浮点。构造、转换和提取向量单个元素的简单方法是使用并集

      typedef union {
          vector4f vec; // processor-specific built-in type
          struct { // human-friendly access for transformations, etc
              float x;
              float y;
              float z;
              float w;
          };
          struct { // human-friendly access for color processing, lighting, etc
              float r;
              float g;
              float b;
              float a;
          };
          float arr[4]; // yet another convenience access
      } Vector4f;
      
      int main()
      {
          Vector4f position, normal, color;
          // human-friendly access
          position.x = 12.3f;
          position.y = 2.f;
          position.z = 3.f;
          position.w = 1.f;
      
          // computer friendly access
          //some_processor_specific_operation(position.vec,normal.vec,color.vec);
          return 0;
      }
      

      如果你选择PlayStation 3多核编程或图形编程,很有可能你会遇到更多这样的事情。

      SDL使用联合来表示事件:。

      我知道我参加聚会有点晚了,但作为一个实际例子,VBScript中的
      变量
      数据类型,我相信,是作为一个
      联合来实现的de>。下面的代码是一个简化的示例,摘自另一篇文章


      实际实现(如文章所述)可以在oaidl.h C头文件中找到。

      你是指C/C++中的union构造吗?我通常看到union用于实现穷人的多态形式。为什么不使用google代码搜索?让你找到大量的实际示例:)@Christian Link不起作用。是的,但我想如果它实际应用的话,比如max_align,如果你使用这样的东西,你应该注意字节的顺序(endian)。这意味着这个代码可能在一台机器(big endian)上起作用,而在另一台机器(little endian)上不起作用它在BE和LE机器上工作。只是结果不同:-)@yesraaj:我最近在我们的AIX机器上使用它来将64位机器标识符转换为字节数组。注意:此机器标识符是AIX特有的。我知道如何使用union,我的朋友也知道,但我想知道它是否最常用使用union来强制转换,就像这是技术上未定义的行为一样(虽然我不知道有什么
      typedef union {
          vector4f vec; // processor-specific built-in type
          struct { // human-friendly access for transformations, etc
              float x;
              float y;
              float z;
              float w;
          };
          struct { // human-friendly access for color processing, lighting, etc
              float r;
              float g;
              float b;
              float a;
          };
          float arr[4]; // yet another convenience access
      } Vector4f;
      
      int main()
      {
          Vector4f position, normal, color;
          // human-friendly access
          position.x = 12.3f;
          position.y = 2.f;
          position.z = 3.f;
          position.w = 1.f;
      
          // computer friendly access
          //some_processor_specific_operation(position.vec,normal.vec,color.vec);
          return 0;
      }
      
      struct tagVARIANT
      {
          union 
          {
              VARTYPE vt;
              WORD wReserved1;
              WORD wReserved2;
              WORD wReserved3;
              union 
              {
                  LONG lVal;
                  BYTE bVal;
                  SHORT iVal;
                  FLOAT fltVal;
                  DOUBLE dblVal;
                  VARIANT_BOOL boolVal;
                  DATE date;
                  BSTR bstrVal;
                  SAFEARRAY *parray;
                  VARIANT *pvarVal;
              };
          };
      };