访问结构联合中结构的第一个字段 [英] Accessing first field of struct in a union of structs

查看:50
本文介绍了访问结构联合中结构的第一个字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有三个结构体,它们共享第一个字段的第一个类型和名称:

I have three structs that share the first type and name of the first field:

struct TYPEA {
  char *name;
  int x,y;   /*or whatever*/
};

struct TYPEB {
  char *name;
  float a[30]; /*or whatever*/
};

struct TYPEC {
  char *name;
  void *w,*z; /*or whatever*/
};

如果我没记错的话,结构体的第一个字段必须从与结构体本身相同的地址开始.

If I remember correctly the first field of a struct is required to start at the same address as the struct itself.

这让我想知道联合是否也是如此:

This makes me wonder if the same holds for a union:

union data {
  struct TYPEA;
  struct TYPEB;
  struct TYPEC;
};

union data *p = function_returning_a_sane_default_for_union_data();
printf("%s", (char*) p);

我有两个关于此的问题:

I have 2 question regarding this:

  1. 是标准要求的联合总是将他们的内容放在同一个地址?
  2. 如果结构都相同,它会起作用吗?字段,所以只是名称不同?

推荐答案

structunion 的第一个元素保证与struct´/union 本身.显然它没有相同的类型!

The first element of a struct or union is guaranteed to have the same address-value as the struct´/union itself. Apparently it has not the same type!

对于您的用法,您不需要演员表,实际上应该避免它:

For your usage, you do not need the cast and actually should avoid it:

6.5.2.3p6:为了简化联合的使用,做了一个特殊的保证:如果联合包含多个共享公共初始序列的结构(见下文),并且联合对象当前包含这些结构之一,允许检查它们中任何一个的公共初始部分,只要联合的完整类型的声明可见.……

6.5.2.3p6: One special guarantee is made in order to simplify the use of unions: if a union contains several structures that share a common initial sequence (see below), and if the union object currently contains one of these structures, it is permitted to inspect the common initial part of any of them anywhere that a declaration of the completed type of the union is visible. …

所以你可以(见下文)很简单

So you could (see below) simply

printf("%s", p->name);

(注意:你对未命名的 union 成员的使用不是标准的编译器.它是一个(非常有用的)gcc 扩展(-fms-extensions,至少也是MSVC 也支持).

(Note: that your usage of unnamed union members is not standard compilant. It is a (very useful) gcc extension (-fms-extensions, at least also supported by MSVC, too).)

但是:您问题中的代码是错误的.您必须为每个联合成员命名或为每个成员指定类型声明符.但是,对于相同的第一个成员,它不会起作用,因为此类未命名成员的成员名称必须是唯一的(否则应该如何单独访问它们?).所以这不会真正起作用.你可以做的是:

But: The code in your question is wrong. You have to name each union member or have the type declarator with each member. With the same first member, It will not weork, though, because the names of the mebers of such unnamed members have to be unique (how else are they supposed to be accesseed individually?). So this will not really work. What you could do is:

union data {
    struct TYPEA typea;
    struct TYPEB typeb;
    struct TYPEC typec;
};

printf("%s", p->typea.name);

即使 struct 当前包含 TYPEB 的值.

even if the struct contains a value of TYPEB currently.

另一种更清晰的方法是将 union 包装到 struct 中:

An alternative and more clear way, would be to wrap the union into a struct:

struct TypeA {
    int x,y;
};

...

struct data {
    char *name;
    union {
        struct TypeA;
        struct TypeB;
        struct TypeC;
    };
};

这也在两个级别使用 gcc 扩展:用于外部 structunion.因此,它需要所有可能路径的唯一名称.如果您想 100% 合规,请像上面一样命名每个成员并使用完整的访问路径.

This also uses the gcc extension at two levels: for the outer struct and the union. As such, it requires unique names for all possible paths. If you want to be 100% compliant, name each member like above and use the full path on access.

注意:我从 union 的内部 struct 中删除了 name 成员,并将其移到了外部 struct.我也改了名字.C 中唯一被广泛接受的命名约定是仅对宏使用全大写.

Note: I removed the name member from the inner structs in the union and moved it to the outer struct. I also changed names. The only well accepted naming convention in C is to use all-uppercase for macros only.

这篇关于访问结构联合中结构的第一个字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆