2017-11-29 12 views
2

C言語で構造体を定義したとします。その構造体のインスタンスを宣言する場合、その前に 'struct'キーワードを含める必要があります。C言語のstructインスタンスの前に 'struct'キーワードを指定する必要があるのはなぜですか?

// Define struct 
struct Book { 
    char title[50]; 
    char author[50]; 
    char subject[100]; 
    int book_id; 
}; 

// Instantiate struct 
int main() 
{ 
    struct Book myBook; 
} 

私の質問:構造体のキーワードは、構造体の任意のインスタンス化の前にするために、なぜそれが必要なのか?コンパイラには、 'Book'が構造体であることを控除するための情報がたくさんあるようです。

typedefを使ってこの問題を回避することができますが、コンパイラが知っているはずのボイラープレートコードのように思えます。

+5

Cでは、構造体と共用体はそれぞれ、グローバル名前空間とは異なる独自の名前空間を持ちます。 'struct'と言って、構造体の名前空間を調べるようにしなければなりません。 –

+1

@RaymondChen:タグの名前空間は、構造体、共用体、列挙型の間で共有されます。たとえば、同じ範囲に 'struct foo'と' union foo'の両方を持つことはできません。ラベルは 'struct'と' union'メンバと同じように、独自の名前空間を取得します。他のすべての識別子(変数名、関数名、列挙定数など)は、「通常の識別子」名前空間にまとめられます。 –

答えて

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; 
} 
+0

これは、常に 'struct'を書くことの煩わしさを和らげるのに十分重大な利点であるかどうかを判断することです(あるいは、デバッグ情報を歴史的に混乱させる' typedef'トリックを使用します)。 –

+0

@MatteoItalia問題は、他のモジュールやライブラリの名前と競合する可能性があることです。キーワードを使用すると、これらの競合を避けることができます。 –

+0

実際にはそうではありません...型は別の名前空間に保持されます。これは、含まれているすべてのライブラリ間で共有されているため、型と別の種類のシンボルとの競合が起こることはまれです。機能の名前が矛盾している場合(これは一般的に起こります)、同じように問題が発生します。 –

0

、あなたはstruct Bookに関連する必要はないの両方struct BookBookという名前のグローバル/ローカルシンボルを持つことができます。 struct statは、statという名前の関数と並んで存在していますが、この機能はPOSIXで使用されています。

明らかにC++が行ったようにtypedefingを自動化することができます(したがって、おそらく無関係のBookstruct Bookが同じ範囲にある可能性が失われます)。しかし、自動化しないと、 typedefをまったく使用しないと、基本的に文脈自由文法が得られますが、typedef(明示的または暗黙的)では、現在有効なtypedefの型のコンテキストをパーサーが管理する必要があります。

#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; 
}); 

(あなたが使用したいことがあります。個人的に、私は、グローバルスコープは、同じ名前の構造体タグと共存持つ可能性にINGのtypedefを自動化好む、と私はやる


構造体/共用体/列挙型(例えばのように_s)を扱っていることを知らせる命名規則と一緒に)。

関連する問題