假设我在C中定义了一个结构。如果我声明了该结构的一个实例,那么我必须包含结构'在它面前的关键字。
// 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来解决这个问题,但这对于编译器应该已经知道的事情看起来就像是样板代码。
答案 0 :(得分:0)
由于使用了关键字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;
}
答案 1 :(得分:0)
根据当前的安排,您可以同时拥有struct Book
和名为Book
的全局/本地符号,该符号不需要与struct Book
相关联。与struct stat
函数一起存在的stat
就是在POSIX中使用此功能的一个很好的例子。
显然,你可以像C ++一样自动化typedefing(从而失去了在同一范围内可能没有Book
和struct Book
的可能性),但我想不会使它自动化语法可能更整洁,因为如果你根本不使用typedef
,你就有了基本的无上下文语法,而typedef
s(显式或隐式)是当前的语境解析器必须维护有效的typedef
ed类型。
就个人而言,我更喜欢自动typedef
使全局范围与同名的struct标记共存的可能性,所以我这样做:
#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;
});
(您可能希望将它与命名约定一起使用,让您知道您正在处理struct / union / enum(例如_s
中的book_s
))。