43

假设我们有一个工会:

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

在我设置例如a = 123之后,是否可以检查联合中的类型?我的方法是将此联合添加到某个结构中,并在 int 时将 uniontype 设置为 1,在 double 时将其设置为 2。

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

有没有更好的解决方案?

4

6 回答 6

37

有没有更好的解决方案?

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

于 2013-05-18T10:30:00.490 回答
7

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

您保留单独的“uniontype”变量的方法是一种非常常见的方法,应该可以很好地工作。

于 2013-05-18T10:31:26.900 回答
4

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

知道存储在 aunion中的类型的唯一方法是使用显式标志(如您的mystruct示例中所示),或者确保当联合具有已知的活动元素时,控制仅流向代码的某些部分。

于 2013-05-18T10:31:48.417 回答
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
  }
于 2013-05-18T10:38:52.323 回答
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);
}

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

于 2013-05-18T10:55:51.420 回答
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);
}
于 2019-04-10T09:27:18.997 回答