嵌套结构语法

pre*_*lic 5 c

我有一个简单的问题..这些有什么区别:

struct myinnerstruct
{
    int x;

};

struct mystruct
{
    struct myinnerstruct m;
    int y;
};
Run Code Online (Sandbox Code Playgroud)

还有这个

struct mystruct
{
    int x;
    struct myinnerstruct
    {
        int y;
    };
    struct myinnerstruct m; 
};
Run Code Online (Sandbox Code Playgroud)

这些都可以告诉我,但我想知道是否有理由选择其中一个.谢谢

Kei*_*son 7

不同之处在于第二个无效.

结构声明中{和之间的内容}是一系列成员声明.您的

    struct myinnerstruct
    {
        int y;
    };
Run Code Online (Sandbox Code Playgroud)

是一种类型声明; 它不会声明封闭结构的成员,因此在该上下文中它是非法的.

可以做到这一点:

struct mystruct
{
    int x;
    struct myinnerstruct
    {
        int y;
    } m;
};
Run Code Online (Sandbox Code Playgroud)

声明m是成员声明,​​所以没关系; 它也声明了类型struct myinnerstruct.但在我看来,它的风格很差.struct myinnerstruct声明struct mystruct完成后,该类型仍然可见; 请参阅下面的解释.

如果你真的想在这样的结构中使用结构,并且你不打算struct myinnerstruct在其他任何地方使用它,你可以不带标记:

struct mystruct
{
    int x;
    struct
    {
        int y;
    } m;
};
Run Code Online (Sandbox Code Playgroud)

但是你不妨宣布y成为其成员struct mystruct.

如果您想struct innerstruct成为命名类型,只需单独声明它,就像在第一个示例中所做的那样.

以下是为什么 struct innerstruct仍然可见的解释.

C99标准(大PDF),第6.2.1条第2款,他说:

对于标识符指定的每个不同实体,标识符仅在称为其范围的程序文本的区域内可见(即,可以使用).由相同标识符指定的不同实体具有不同的范围,或者在不同的名称空间中.范围有四种:函数,文件,块和函数原型.(函数原型是声明其参数类型的函数的声明.)

C90和C11标准的措辞基本相同.

结构声明中的{大括号}不定义块,也不定义任何其他可能的范围,因此在大括号之间声明的任何内容都不限定为该区域; 它必须限定在某些周围环境中.碰巧语法允许您struct myinnerstruct在另一个结构定义中声明- 但前提是它只是成员定义的一部分.我认为这只是因为该语言的设计者没有采取任何额外的努力来禁止它; 这只是其他规则的副作用.你可以做到,但我不推荐它.