2011-09-07 113 views
5

我有一个快速question..is有这些有什么区别:嵌套结构语法

struct myinnerstruct 
{ 
    int x; 

}; 

struct mystruct 
{ 
    struct myinnerstruct m; 
    int y; 
}; 

和本

struct mystruct 
{ 
    int x; 
    struct myinnerstruct 
    { 
     int y; 
    }; 
    struct myinnerstruct m; 
}; 

这些工作都尽可能我可以告诉,但我想知道是否有理由选择一个或另一个。谢谢

+0

第二个变体是否合法C? –

+0

我还没有真正能够在网上找到它的任何例子。我的测试都返回相同的结果。所以AFAIK,它是。 – prelic

+0

下面的内容也会起作用,使第二个缩短一点:struct mystruct {int x; struct myinnerstruct {int y; } m; };恕我直言,在另一个'struct'内定义一个'struct'的最好理由是当内部''struct'被独占使用并且可能重复地作为外部'struct'的成员时,也就是说'struct'必须有许多“团体”为不同的目的存储类似的信息。 –

回答

7

区别在于第二个是无效的。

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

struct myinnerstruct 
    { 
     int y; 
    }; 

是一种类型声明;它没有声明封闭结构的成员,所以在这种情况下它是非法的。

什么你可以做的是:

struct mystruct 
{ 
    int x; 
    struct myinnerstruct 
    { 
     int y; 
    } m; 
}; 

m的声明是一个成员声明,​​所以它的确定;它还声明了类型struct myinnerstruct。但在我看来,这是不好的风格。在struct mystruct的声明完成后,struct myinnerstruct类型仍然可见;请参阅下面的解释。

如果你真的想这样的一个结构内的结构,而你不打算使用struct myinnerstruct其他地方,你可以离开它没有一个标签:

struct mystruct 
{ 
    int x; 
    struct 
    { 
     int y; 
    } m; 
}; 

但你还不如申报y作为struct mystruct的成员。

如果你想让struct innerstruct成为一个命名类型,只需单独声明它,就像你在第一个例子中一样。

下面是对的解释,为什么struct innerstruct仍然可见。

C99 standard(大PDF),第6.2.1节第2段表示:

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

的C90和C11的标准具有基本上相同的措辞。

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

+0

所以,如果我想要一个[内部]结构不能被自己声明(但只能通过外部结构声明),我应该嵌套定义,但留下一个没有标签的内部结构,如你的例子? – prelic

+0

@prelic:这取决于。为什么你首先需要一个内部结构?在您向我们展示的(可能是)简化代码中,只有一个'struct innerstruct'实例,它是'struct mystruct'的成员。为什么不平坦化结构,以便'struct innerstruct'的成员变成'struct mystruct'的直接成员?我不一定说这是正确的解决方案,但知道为什么不是(如果不是),将有助于确定如何解决实际问题。 –

+0

是的,我在这个例子中意识到,扁平我的结构是微不足道的。但是,我实际上在应用这一点,并不是那么清楚。我与(合理的)大型结构一起工作,这些结构构成了更大的结构。无论组件结构在结构集外是否可见,这都很重要。 – prelic

1

选择一个或其他的理由是传统的期望。

嵌套在另一个中的结构声明不会在别处被重用,即使它可以。

另外,由于没有将相同抽象级别的东西并排放置,所以会产生心理冲突。这样做是完全合法的,但它会让代码变得更难以理解,也许更令人恼火。