C语言 如何检查当前在联合体中使用的类型?

8yoxcaq7  于 2023-08-03  发布在  其他
关注(0)|答案(7)|浏览(100)

假设我们有一个联合:

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

字符串
在我设置了,例如,a=123,我的方法是将这个联合添加到某个结构中,当它是int时,将uniontype设置为1,当它是double时,将uniontype设置为2。

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


有没有更好的解决办法?

eoigrqb6

eoigrqb61#

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

njthzxwz

njthzxwz2#

C不会自动跟踪联合中当前正在使用的字段。(事实上,我相信从“错误”字段阅读会导致实现定义的行为。)因此,由您的代码来跟踪当前使用/填写的是哪个字段。
您保持一个单独的'uniontype'变量的方法是一种非常常见的方法,应该可以很好地工作。

vcudknz3

vcudknz33#

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

ycggw6v2

ycggw6v24#

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

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
  }

字符串

apeeds0o

apeeds0o5#

  • 警告:以下内容仅供学习:*

你可以使用一些丑陋的技巧来做到这一点(只要你的联合中的数据类型有不同的大小,这就是目前的情况):

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

字符串
但我建议你永远不要这么做。

x7rlezfr

x7rlezfr6#

也许我的变种在起作用

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

字符串

00jrzges

00jrzges7#

没有直接的方法来检查存储在联合体中的数据类型。因此,您负责跟踪联合中的类型。
为了更好的可读性,使用Enum而不是int可能是一个好主意。

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

typedef enum someEnum{
    INT,
    DOUBLE
} myuniontype;

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

int main() {
    mystruct my_container;
    my_container.uniontype = myuniontype::INT;
    my_container.numbers.a=5;
    switch (my_container.uniontype) {
        case myuniontype::INT:
            std::cout<<my_container.numbers.a<<std::endl;
            break;
        case myuniontype::DOUBLE:
            std::cout<<my_container.numbers.b<<std::endl;
            break;
    }
    return 0;
}

字符串

相关问题