C语言 使用 C 中的结构联合

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20752551/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 10:32:32  来源:igfitidea点击:

Working with a union of structs in C

cunions

提问by rikkit

Say I have the following types:

假设我有以下类型:

typedef struct TYPEA
{
    int type;
    char[12] id;
} TYPEA;

typedef struct TYPEB
{
    int type;
    int value;
} TYPEB;

I want to use create a union of these types and 'int', so that I can access the "type" int without needing to know whether TYPEA or TYPEB is stored in the union (the value of int lets me determine which is actually stored there). I can't get the right syntax though.

我想使用创建这些类型和“int”的联合,这样我就可以访问“类型”int,而无需知道联合中是否存储了 TYPEA 或 TYPEB(int 的值让我确定实际存储的是哪个那里)。虽然我无法获得正确的语法。

My union:

我的工会:

typedef union MEMBER
{
    int type;
    struct TYPEA a;
    struct TYPEB b;
} MEMBER;

The union is accessed via:

通过以下方式访问联合:

typedef struct WRAPPER
{
    union MEMBER* member;
    struct WRAPPER* next;
} WRAPPER;

Questions:

问题:

  1. (With 'w' as a pointer to an allocated WRAPPER struct) Accessing using w->member->a.idgives "request for member 'id' in something not a structure or union.
  2. Can I assign a pointer to an already malloc'd TYPEA/B to w->member directly? Or does a union need to be malloced specially?
  1. (使用 'w' 作为指向分配的 WRAPPER 结构的指针)访问 usingw->member->a.id会在不是结构或联合的东西中提供“对成员 'id' 的请求。
  2. 我可以将指向已经 malloc 的 TYPEA/B 的指针直接分配给 w->member 吗?或者联合需要特别malloced?

Thanks.

谢谢。

回答by Andrey Mishchenko

  1. Use w->member->type.
  2. You need to allocate the unionspecifically.
  1. 使用w->member->type.
  2. 您需要union专门分配。

One note that may be a point of misunderstanding is that the unionholds EITHER the int, or TYPEA, or TYPEB, so in particular you cannot rely on your int type;in the union to tell you which structthe union holds.

一个可能引起误解的注意事项是,union持有int, 或TYPEA, 或TYPEB,因此特别是您不能依靠您int type;在工会中来告诉您struct工会持有哪个。

Edit to respond to question in comments:

编辑以回答评论中的问题:

You probably want something like this:

你可能想要这样的东西:

struct TYPEA {
  char data[30]; // or whatever
};

struct TYPEB {
  double x, y; // or whatever
};

struct some_info {
  int type; // set accordingly
  union {
    struct TYPEA a;
    struct TYPEB b;
  } data; // access with some_info_object.data.a or some_info_object.data.b
};

回答by Zach Rattner

  1. You defined the memberfield as a pointer, so you should use w->member->typeinstead of w->member.type.
  2. You should mallocthe union type. When you allocate a union, you'll get a structure that has a sizeofequal to the largest element in the union. If you try to copy structures into union pointers, you'll mess up the alignment.
  1. 您将该member字段定义为指针,因此您应该使用 w->member->type代替w->member.type
  2. 你应该malloc是联合类型。当您分配联合时,您将获得一个结构,该结构的 asizeof等于联合中的最大元素。如果您尝试将结构复制到联合指针中,则会弄乱对齐方式。

回答by sqykly

w->member.typeshould be w->member->typebecause w->memberis a pointer.

w->member.type应该是w->member->type因为w->member是一个指针。

I don't know off the top of my head whether C will let you assign a TYPEA*or TYPEB*to a MEMBER*- somehow I doubt it. You can always (MEMBER*)it, but I would consider recomposing the structs to remove the inttag and instead declare one structthat includes the tag and a unionof TYPEAand TYPEB. The structs ideally shouldn't need to be concerned with the fact that they're in a union.

我不知道 C 是否会让您分配 aTYPEA*TYPEB*a MEMBER*- 不知何故,我对此表示怀疑。你总是(MEMBER*)可以,但我会考虑重新组合structs 以删除int标签,而是声明一个struct包含标签和 aunionTYPEAand TYPEBstruct理想情况下,s 不需要担心它们位于union.

回答by backscattered

You might want to check out the code in my question:

您可能想查看我的问题中的代码:

Union of structs with common first member

具有共同第一成员的结构联合

Essentially, I do what you want but I'm using an inner struct (containedin the example) that's common to the two types. This struct can then be cast to gain access to the common elements of both types.

从本质上讲,我做你想做的,但我使用的contained是两种类型通用的内部结构(在示例中)。然后可以对该结构进行强制转换以访问两种类型的公共元素。