C语言中,结构,定义上的细微差别
In C language, Structure, subtle difference in definition
我已经看到下面用于定义结构的格式
typedef struct Tag
{
type Member1;
type Member2;
<and so on..>
};
有些地方我看到了下面定义结构的格式
typedef struct Tag
{
type Member1;
type Member2;
<and so on..>
} Tag;
有些地方我看到了下面定义结构的格式
typedef struct
{
type Member1;
type Member2;
<and so on..>
} Tag;
如果您注意到 Tag
语法在 struct
之后并且也在右大括号处。
问题。
1) 3有什么区别?
2) 一个比另一个更受青睐吗?或者什么时候您可能希望使用其中一个的最佳条件?
第一个示例为名为 Tag 的结构创建了一个定义。第二个还创建了一个名为 Tag 的变量(恰好是一个 Tag 结构)。第三个创建具有指定结构的名为 Tag 的变量 - 但该结构从未命名,因此您不能再次使用它。
用哪个?我个人会使用第一个,然后单独声明任何类型的 Tag 变量。如果您试图删除一行代码,那么第二行就可以正常工作。如果您只打算使用该结构一次,则可以使用第三个。
根据 C 标准(6.2.3 标识符的命名空间)
1 If more than one declaration of a particular identifier is visible
at any point in a translation unit, the syntactic context
disambiguates uses that refer to different entities. Thus, there are
separate name spaces for various categories of identifiers, as
follows:
— label names (disambiguated by the syntax of the label declaration
and use);
— the tags of structures, unions, and enumerations (disambiguated by
following any32) of the keywords struct, union, or enum);
— the members of structures or unions; each structure or union has a
separate name space for its members (disambiguated by the type of the
expression used to access the member via the . or -> operator);
— all other identifiers, called ordinary identifiers (declared in
ordinary declarators or as enumeration constants).
这是
struct Tag
{
type Tag;
<and so on..>
};
一个名为Tag
的结构声明,同时它是一个结构定义,因为它不仅引入了类型struct Tag
,还声明了它的成员。
您可以先声明一个结构,然后再定义它。例如
#include <stdio.h>
struct Tag;
struct Tag
{
int Tag;
};
int main(void)
{
struct Tag Tag = { .Tag = 10 };
printf( "Tag.Tag = %d\n", Tag.Tag );
return 0;
}
程序输出为
Tag.Tag = 10
在此声明中
struct Tag
{
type Tag;
<and so on..>
} Tag;
声明了一个 struct Tag
类型的对象,标识符 Tag
。该结构有一个名为 Tag
的数据成员。因此声明了两个实体:类型 struct Tag
和结构类型名称为 Tag
的对象。
在此声明中
struct
{
type Tag;
<and so on..>
} Tag;
声明了一个未命名结构类型的对象,标识符为 Tag
。这个声明的问题是你不能引用对象的类型。
你可以再遇到一个这样的声明
typedef struct Tag
{
type Tag;
<and so on..>
} Tag;
在此 typedef 声明中,标识符 Tag
用作类型 struct Tag
.
的别名
或
typedef struct
{
type Tag;
<and so on..>
} Tag;
在此 typedef 声明中,标识符 Tag
用作未命名结构类型的别名。
C 2011 允许声明匿名结构。
来自 C 标准(6.7.2.1 结构和联合说明符)
13 An unnamed member of structure type with no tag is called an
anonymous structure; an unnamed member of union type 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.
我已经看到下面用于定义结构的格式
typedef struct Tag
{
type Member1;
type Member2;
<and so on..>
};
有些地方我看到了下面定义结构的格式
typedef struct Tag
{
type Member1;
type Member2;
<and so on..>
} Tag;
有些地方我看到了下面定义结构的格式
typedef struct
{
type Member1;
type Member2;
<and so on..>
} Tag;
如果您注意到 Tag
语法在 struct
之后并且也在右大括号处。
问题。
1) 3有什么区别?
2) 一个比另一个更受青睐吗?或者什么时候您可能希望使用其中一个的最佳条件?
第一个示例为名为 Tag 的结构创建了一个定义。第二个还创建了一个名为 Tag 的变量(恰好是一个 Tag 结构)。第三个创建具有指定结构的名为 Tag 的变量 - 但该结构从未命名,因此您不能再次使用它。
用哪个?我个人会使用第一个,然后单独声明任何类型的 Tag 变量。如果您试图删除一行代码,那么第二行就可以正常工作。如果您只打算使用该结构一次,则可以使用第三个。
根据 C 标准(6.2.3 标识符的命名空间)
1 If more than one declaration of a particular identifier is visible at any point in a translation unit, the syntactic context disambiguates uses that refer to different entities. Thus, there are separate name spaces for various categories of identifiers, as follows:
— label names (disambiguated by the syntax of the label declaration and use);
— the tags of structures, unions, and enumerations (disambiguated by following any32) of the keywords struct, union, or enum);
— the members of structures or unions; each structure or union has a separate name space for its members (disambiguated by the type of the expression used to access the member via the . or -> operator);
— all other identifiers, called ordinary identifiers (declared in ordinary declarators or as enumeration constants).
这是
struct Tag
{
type Tag;
<and so on..>
};
一个名为Tag
的结构声明,同时它是一个结构定义,因为它不仅引入了类型struct Tag
,还声明了它的成员。
您可以先声明一个结构,然后再定义它。例如
#include <stdio.h>
struct Tag;
struct Tag
{
int Tag;
};
int main(void)
{
struct Tag Tag = { .Tag = 10 };
printf( "Tag.Tag = %d\n", Tag.Tag );
return 0;
}
程序输出为
Tag.Tag = 10
在此声明中
struct Tag
{
type Tag;
<and so on..>
} Tag;
声明了一个 struct Tag
类型的对象,标识符 Tag
。该结构有一个名为 Tag
的数据成员。因此声明了两个实体:类型 struct Tag
和结构类型名称为 Tag
的对象。
在此声明中
struct
{
type Tag;
<and so on..>
} Tag;
声明了一个未命名结构类型的对象,标识符为 Tag
。这个声明的问题是你不能引用对象的类型。
你可以再遇到一个这样的声明
typedef struct Tag
{
type Tag;
<and so on..>
} Tag;
在此 typedef 声明中,标识符 Tag
用作类型 struct Tag
.
或
typedef struct
{
type Tag;
<and so on..>
} Tag;
在此 typedef 声明中,标识符 Tag
用作未命名结构类型的别名。
C 2011 允许声明匿名结构。 来自 C 标准(6.7.2.1 结构和联合说明符)
13 An unnamed member of structure type with no tag is called an anonymous structure; an unnamed member of union type 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.