代码之家  ›  专栏  ›  技术社区  ›  afiori

访问结构并集中结构的第一个字段

  •  3
  • afiori  · 技术社区  · 7 年前

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

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

    1. 让他们的内容始终在同一个地址?
    2. 如果所有结构都具有相同的 菲尔斯,只是名字上的不同?
    1 回复  |  直到 7 年前
        1
  •  3
  •   too honest for this site    7 年前

    a的第一个元素 struct union 保证具有与 struct´/

    对于您的使用,您不需要强制转换,实际上应该避免:

    为了简化联合的使用,我们做出了一项特殊保证:如果联合包含多个共享公共初始序列的结构(见下文),并且如果联合对象当前包含其中一个结构,则允许检查其中任何结构的公共初始部分,只要可以看到联合的完整类型声明。

    所以你 (见下文)简单

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

    (注意:您使用的未命名 -fms-extensions ,至少也得到MSVC的支持。)

    能够 do是:

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

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

    即使 结构 TYPEB 目前。


    另一种更清晰的方法是将 变成一个 :

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

    这也在两个级别上使用了gcc扩展:用于外部 结构 . 因此,所有可能的路径都需要唯一的名称。如果您希望完全兼容,请按上述方式命名每个成员,并在访问时使用完整路径。

    注意:我删除了 name 来自内部的成员 协会 把它移到外面 . 我还改了名字。C中唯一被广泛接受的命名约定是只对宏使用全大写。