C:如何访问不同类型的匿名或未命名的嵌套结构

C: How to access different types of anonymous or unnamed nested structs

我注意到有几种方法可以在 C:

中的其他结构中定义结构
struct s {
    int abc;

    struct {
        int a;
    };

    struct {
        int b;
    } intern;

    struct i {
        int c;
    };

    struct i2 {
        int d;
    } intern2;

    struct i3 {
        int e;
    };
    struct i3 intern3;
};

这个结构使用 gcc 或 g++ 编译得很好,所以我假设所有参数都可以通过某种方式访问​​。我这样试过:

int main(int argc, char const *argv[])
{
    struct s mystruct;

    mystruct.abc = 0;
    mystruct.a = 1;
    mystruct.intern.b = 2;
    mystruct.c = 3; // <-- does not compile
    mystruct.intern2.d = 4;
    mystruct.intern3.e = 5;

    return 0;
}

除了访问 mystruct.c 之外,所有内容都可以编译(编译错误消息是 ‘struct s’ has no member named ‘c’)。我是否以正确的方式访问结构参数?有其他选择吗?如何访问 c 参数?

在您的代码中,

struct i {
        int c;
    };

没有struct i类型的成员变量,也不符合匿名结构注意。如果您创建该类型的变量,您将能够访问成员变量 c,类似于您使用 intern3 变量为 struct i3 所做的。

添加一些关于您看到的错误消息,

struct s has no member named c

因为在匿名结构的情况下,成员 被视为 包含结构的直接成员。如果 struct 定义带有 标记 ,则该结构不是匿名结构,并且该结构的成员需要访问该类型的结构变量。


注意:

关于匿名结构,引用C11,章节§6.7.2.1,(强调我的

An unnamed member whose type specifier is a structure specifier with no tag is called an anonymous structure; an unnamed member whose type specifier is a union specifier with no tag is called an anonymous union. The members of an anonymous structure or union are considered to be members of the containing structure or union. This applies recursively if the containing structure or union is also anonymous.

成员 cstrut i 内部声明。而且您没有为 struct i.

创建任何变量

因此,您无法访问成员 c

当您提到 mystruct.c 时,它期望 c 是结构 s 的成员,但事实并非如此。

来自gcc docs

As permitted by ISO C11 and for compatibility with other compilers, GCC allows you to define a structure or union that contains, as fields, structures and unions without names. For example:

 struct {
   int a;
   union {
     int b;
     float c;
   };
   int d;
 } foo;

In this example, you are able to access members of the unnamed union with code like ‘foo.b’.

您能够到达 mystruct.a 因为该结构没有标签。您无法获取 mystruct.c,因为 c 的包含结构具有标记 i

变化:

 struct i {
        int c;
    };

struct {
    int c;
}

你应该可以到达 mystruct.c

不给狗起名字就不能叫它

这正是 unnamed 所说的 - 它没有名称,因此您无法通过名称访问它。

在结构中使用未命名成员的唯一原因是,如果您正在镜像一个外部给定的结构,并且您不关心它的特定部分,那么您只命名您想要访问的部分。