C:Can';我不明白这种类型的结构和变量的第二和第三种声明方法是如何有效的?
以下是我书中给出的三种方法:- (一) 在第二种方法中,为什么结构类型声明中的右大括号后面不跟分号 第三种方法对我来说没有任何意义,因为我们甚至没有声明结构的名称C:Can';我不明白这种类型的结构和变量的第二和第三种声明方法是如何有效的?,c,C,以下是我书中给出的三种方法:- (一) 在第二种方法中,为什么结构类型声明中的右大括号后面不跟分号 第三种方法对我来说没有任何意义,因为我们甚至没有声明结构的名称 那么,这两种方法如何有效呢?在定义结构时,您还可以定义该结构的一个或多个实例。这就是第二个和第三个示例中发生的情况 两者之间的区别在于,一个在定义类型时声明三个structbook类型的变量,而另一个声明三个类型为匿名结构的变量。在后一种情况下,这意味着不能定义该类型的其他变量,因为在定义结构时,该结构没有名称,也没有关联的typed
那么,这两种方法如何有效呢?在定义
结构时,您还可以定义该结构的一个或多个实例。这就是第二个和第三个示例中发生的情况
两者之间的区别在于,一个在定义类型时声明三个structbook
类型的变量,而另一个声明三个类型为匿名结构的变量。在后一种情况下,这意味着不能定义该类型的其他变量,因为在定义结构时,该结构没有名称,也没有关联的typedef
,您还可以定义该结构的一个或多个实例。这就是第二个和第三个示例中发生的情况
两者之间的区别在于,一个在定义类型时声明三个structbook
类型的变量,而另一个声明三个类型为匿名结构的变量。在后一种情况下,这意味着不能定义该类型的其他变量,因为该结构没有名称,也没有关联的整个结构的typedef
struct {
int field1;
char field2;
// ...
}
本身就是一种类型。因此,可以像使用其他类型一样在变量声明中使用它。它们都是相同的形式
<type> <identifier>;
是有效的变量声明,正如
int bar;
是。记住新行在C中没有任何语法意义
使用struct
,您可以给它一个名称(称为struct标记),如下所示:
struct foo {
int field1;
char field2;
// ...
};
如果这样做,您可以稍后通过编写
struct foo
而不是重复它的所有字段。这实际上是最常见的用法。的整个结构
struct {
int field1;
char field2;
// ...
}
本身就是一种类型。因此,可以像使用其他类型一样在变量声明中使用它。它们都是相同的形式
<type> <identifier>;
是有效的变量声明,正如
int bar;
是。记住新行在C中没有任何语法意义
使用struct
,您可以给它一个名称(称为struct标记),如下所示:
struct foo {
int field1;
char field2;
// ...
};
如果这样做,您可以稍后通过编写
struct foo
而不是重复它的所有字段。这实际上是最常见的用法。TL/DR-C声明语法允许所有三种方法
耐心点,这需要一段时间
让我们从声明的语法开始:
declaration:
declaration-specifiers init-declarator-listopt ;
static_assert-declaration
declaration-specifiers:
storage-class-specifier declaration-specifiersopt
type-specifier declaration-specifiersopt
type-qualifier declaration-specifiersopt
function-specifier declaration-specifiersopt
alignment-specifier declaration-specifiersopt
init-declarator-list:
init-declarator
init-declarator-list , init-declarator
init-declarator:
declarator
declarator = initializer
我们的声明说明符是静态常量int
,声明符是*foo[N]
,初始值设定项是{&bar,&blah,…}
就您的问题而言,我们感兴趣的是类型说明符
,特别是结构或联合说明符
:
结构定义本身是一个类型说明符,就像int
或double
等
但是,如果没有标记名,您将无法在将来的声明中引用相同的结构类型。您当然可以重复另一个变量的定义:
struct { int a; int b; } y;
但是x
和y
的类型是不同的-编译器认为每个struct
定义是不同的类型,即使它们具有相同的内容
现在,记住上面的一般声明语法,声明中的声明器列表是可选的。这就是允许我们仅使用标记名声明结构的原因(尽管根据上述约束,如果不声明此类型的变量,则必须包含标记名):
因为从上面的语法来看:
struct foo x;
| |
+---+----+
|
V
type-specifier
第一个声明创建struct foo
类型,并将x
声明为该类型的变量。第二个声明使用先前定义的struct foo
类型来声明变量y
基本上,C声明语法,特别是在结构、联合和枚举方面,是相当灵活的,并且书中列出的所有方法都同样有效。TL/DR-C声明语法允许所有三种方法
耐心点,这需要一段时间
让我们从声明的语法开始:
declaration:
declaration-specifiers init-declarator-listopt ;
static_assert-declaration
declaration-specifiers:
storage-class-specifier declaration-specifiersopt
type-specifier declaration-specifiersopt
type-qualifier declaration-specifiersopt
function-specifier declaration-specifiersopt
alignment-specifier declaration-specifiersopt
init-declarator-list:
init-declarator
init-declarator-list , init-declarator
init-declarator:
declarator
declarator = initializer
我们的声明说明符是静态常量int
,声明符是*foo[N]
,初始值设定项是{&bar,&blah,…}
就您的问题而言,我们感兴趣的是类型说明符
,特别是结构或联合说明符
:
结构定义本身是一个类型说明符,就像int
或double
等
但是,如果没有标记名,您将无法在将来的声明中引用相同的结构类型。您当然可以重复另一个变量的定义:
struct { int a; int b; } y;
但是x
和y
的类型是不同的-编译器认为每个struct
定义是不同的类型,即使它们具有相同的内容
现在,记住上面的一般声明语法,声明中的声明器列表是可选的。这就是允许我们仅使用标记名声明结构的原因(尽管根据上述约束,如果不声明此类型的变量,则必须包含标记名):
因为从上面的语法来看:
struct foo x;
| |
+---+----+
|
V
type-specifier
第一个声明创建struct foo
类型,并将x
声明为该类型的变量。第二个声明使用先前定义的struct foo
类型来声明v