如何检查联合中当前使用的类型?

时间:2013-05-18 10:28:26

标签: c unions

让我们说我们有一个联盟:

typedef union someunion {
    int a;
    double b;
} myunion;

我可以在设置之后检查哪种类型的联合一个= 123? 我的方法是将这个联合添加到某个结构中,并在它为int时将uniontype设置为1,当它为double时将其设置为2.

typedef struct somestruct {
    int uniontype
    myunion numbers;
} mystruct;

有没有更好的解决方案?

6 个答案:

答案 0 :(得分:18)

  

有没有更好的解决方案?

不,您展示的解决方案是最好的(也是唯一的)解决方案。 union非常简单 - 它们不会“跟踪”你分配给你的内容。他们所做的就是让你为所有成员重用相同的内存范围。除此之外,它们不提供任何其他内容,因此将它们封装在struct中并使用“类型”字段进行跟踪正是要做的事情。

答案 1 :(得分:6)

C不会自动跟踪当前正在使用的联合中的哪个字段。 (事实上​​,我认为从"错误"字段中读取会导致实现定义的行为。)因此,您的代码需要跟踪当前使用/填写的代码。

您保持单独的联盟类型的方法'变量是一种非常常见的方法,应该可以正常工作。

答案 2 :(得分:3)

无法直接查询当前存储在union中的类型。

了解union中存储的类型的唯一方法是使用显式标志(如mystruct示例中所示),或确保控件仅在代码的某些部分流动时联盟有一个已知的活跃元素。

答案 3 :(得分:2)

根据应用程序的不同,如果它是一个短期对象,您可以对控制流中的类型进行编码,即。两个案件都有单独的块/功能

  struct value {
      const char *name;
      myunion u;
  };

  void throwBall(Ball* ball)
  {
     ...
     struct value v;
     v.name = "Ball"; v.u.b = 1.2;
     process_value_double(&v);      //double
     struct value v2;
     v2.name = "Age";
     v2.u.a = 19;
     check_if_can_drive(&v2);       //int
     ...
  }

  void countOranges()
  {
       struct value v;
       v.name = "counter";
       v.u.a = ORANGE;
       count_objects(&v);          //int
  }

答案 4 :(得分:2)

警告:以下内容仅供学习之用:

您可以使用一些丑陋的技巧(只要您的联合中的数据类型具有不同的大小,这是当前情况):

#include <stdio.h>

typedef union someunion {
  int a;
  double b;
} myunion;

typedef struct somestruct {
  int uniontype;
  myunion numbers;
} mystruct;


#define UPDATE_CONTENT(container, value) if ( \
                                             ((sizeof(value) == sizeof(double)) \
                                              ? (container.uniontype = ((container.numbers.b = value), 2)) \
                                              : (container.uniontype = ((container.numbers.a = value), 1))))

int main()
{
  mystruct my_container;

  UPDATE_CONTENT(my_container, 42);
  printf("%d\n", my_container.uniontype);
  UPDATE_CONTENT(my_container, 37.1);
  printf("%d\n", my_container.uniontype);
  return (0);
}

但我建议你永远不要这样做。

答案 5 :(得分:0)

也许我的变体正在帮助

struct Table
{
    char mas[10];
    int width;
    int high;
    union stat
    {
        int st;
        char v;
    } un;
};


Table tble[2];
strcpy(tble[0].mas, "box");
tble[0].high = 12;
tble[0].width = 14;
tble[0].un.v = 'S';

strcpy(tble[1].mas, "bag");
tble[1].high = 12;
tble[1].width = 14;
tble[1].un.st = 40;

//struct Table *ptbl = &tble[0];
//ptbl++;

for (int i = 0; i < 2; i++)
{
    void *pt = &tble[i].un;
    if(*((char*)pt) == 'S')     
        sort(put_on_bag_line);
    else
        sort(put_on_box_line);
}