为什么';结构';关键字在C中的结构实例之前?
假设我在C中定义了一个结构。如果我声明了该结构的一个实例,我必须在它前面包含'struct'关键字为什么';结构';关键字在C中的结构实例之前?,c,struct,typedef,C,Struct,Typedef,假设我在C中定义了一个结构。如果我声明了该结构的一个实例,我必须在它前面包含'struct'关键字 // Define struct struct Book { char title[50]; char author[50]; char subject[100]; int book_id; }; // Instantiate struct int main() { struct Book myBook; } 我的问题:为什么struct关键字必须先于struc
// Define struct
struct Book {
char title[50];
char author[50];
char subject[100];
int book_id;
};
// Instantiate struct
int main()
{
struct Book myBook;
}
我的问题:为什么struct关键字必须先于struct的任何实例化?编译器似乎有足够的信息来推断“Book”是一个结构
我知道你可以通过使用typedef来解决这个问题,但这看起来就像是编译器应该已经知道的锅炉板代码。由于使用关键字struct,这些类型的union和enum名称可以形成自己的名称空间,而不会与其他实体的名称冲突 比如说
#include <stdio.h>
int main(void)
{
struct Book
{
const char *Book;
} Book = { "The first favorite book" };
struct Book otherBook = { .Book = "The second favorite book" };
puts( Book.Book );
puts( otherBook.Book );
return 0;
}
#包括
内部主(空)
{
结构书
{
const char*Book;
}Book={“最喜欢的书”};
struct Book otherBook={.Book=“第二喜爱的书”};
放(书,书);
放置(otherBook.Book);
返回0;
}
按照当前的安排,您可以同时拥有结构书
和名为Book
的全局/本地符号,该符号不需要与结构书
相关struct stat
与名为stat
的函数一起存在,这是POSIX中使用此功能的一个很好的例子
显然,你可以像C++那样自动完成Type Debug,这样就失去了在一个范围内可能有一个无关的<代码> < < /COD> >和
s(显式或隐式),解析器必须维护当前有效的typedef
ed类型的上下文typedef
就我个人而言,我更喜欢自动
typedef
ing,而不是让全局范围与同名结构标记共存,因此我:
#define Struct(Nm,...) typedef struct Nm Nm; struct Nm __VA_ARGS__
#define Union(Nm,...) typedef union Nm Nm; union Nm __VA_ARGS__
#define Enum(Nm,...) enum Nm __VA_ARGS__; typedef enum Nm Nm
Struct(Book,{
char title[50];
char author[50];
char subject[100];
int book_id;
});
(您可能希望将其与一个命名约定一起使用,该命名约定让您知道您正在处理一个结构/联合/枚举(例如,
\u s
,如在book\u s
)。在C中,结构和联合都有自己的名称空间,不同于全局名称空间。您必须说struct
,这样它才知道如何查看struct名称空间。@RaymondChen:标记名称空间在结构、联合和枚举之间共享-例如,不能让struct foo
和union foo
都在同一范围内。标签有自己的名称空间,就像struct
和union
成员一样。所有其他标识符(变量名、函数名、枚举常量等)都集中到“普通标识符”名称空间中。判断这是否是一个足以抵消一直编写struct
的麻烦的优势(或者使用typedef
技巧,这在历史上混淆了调试信息)是留给读者的。@MatteoItalia问题是,与其他模块或库中的名称可能会有冲突。使用关键字可以避免这些冲突。不是真的……它只是将类型保留在一个单独的命名空间中,该命名空间仍然在所有包含的库之间共享,因此它有助于防止类型和另一种符号。如果有冲突的函数名(通常会发生这种情况)你也有麻烦。@MatteoItalia你在自相矛盾。如果你说的是单独的名称空间,那么你就是在证实我的说法。你只是不明白你自己在说什么。有一个用于结构的名称空间,一个用于联合的名称空间,还有一个用于所有其他名称空间;它们中的每一个都在所有li之间共享我想说的是,这是一种错误的分离——你希望每个库都有一个名称空间,而不是每种实体都有一个名称空间(不同库之间仍然可能有冲突的名称)。