为什么必须结构'关键字在C中先于struct实例?

时间:2017-11-29 14:58:33

标签: c struct typedef

假设我在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来解决这个问题,但这对于编译器应该已经知道的事情看起来就像是样板代码。

2 个答案:

答案 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(从而失去了在同一范围内可能没有Bookstruct 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))。