C-在结构结合中访问结构的第一字段



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

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*/
};

如果我没记错的话,必须在与结构本身相同的地址开始启动结构的第一个字段。

这让我想知道联盟是否相同:

union data {
  struct TYPEA;
  struct TYPEB;
  struct TYPEC;
};
union data *p = function_returning_a_sane_default_for_union_data();
printf("%s", (char*) p);

我有2个问题:

  1. 是标准要求的工会始终在同一地址上拥有他们的内容?
  2. 如果结构都具有相同的fiels,仅在名称上有所不同?

structunion的第一个元素保证具有与struct´/联合本身相同的地址值。显然它没有相同的类型!

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

6.5.2.3p6:为了简化工会的使用而做出一种特殊保证:如果联合包含几个共享共同初始序列的结构(请参见下文),以及联合对象当前包含其中一种结构之一,可以在任何地方都可以检查其中的任何一个共同的初始部分,以宣告已完成的工会类型。…

所以您可以(见下文)简单

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

(注意:您对未命名的union成员的使用不是标准编译剂。它是(非常有用的)GCC扩展(-fms-extensions,至少也由MSVC支持)。)

但是:问题中的代码是错误的。您必须命名每个联合成员或具有每个成员的类型声明人。但是,对于同一个第一个成员,它不会引起Weork,因为此类不愿透露姓名的成员的名称必须是唯一的(还应该如何单独访问它们?)。因此,这不会真正起作用。您的可以做什么是:

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

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

即使struct当前包含TYPEB的值。


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

struct TypeA {
    int x,y;
};
...
struct data {
    char *name;
    union {
        struct TypeA;
        struct TypeB;
        struct TypeC;
    };
};

这还使用了两个级别的GCC扩展名:对于外部structunion。因此,它需要所有可能的路径的唯一名称。如果您想符合100%的符合条件,请命名每个成员上面的成员,并在访问时使用完整的路径。

注意:我从union中的内struct s中删除了name成员,并将其移至外部struct。我也更改了名称。C中唯一公认的命名约定是仅将全填充酶用于宏。

相关内容

  • 没有找到相关文章

最新更新