2016-11-12 4 views
1

ここに私が何をしているのかの例があります。この最初のコードは機能しません。この割り当てが関数外で動作しないのはなぜですか?

typedef struct { 
    char *desc; 
    unsigned quantity; 
} item; 

item *inventory[INVENTORY_SIZE]; 

item thing = { "This is a thing.", 2 }; 
inventory[0] = &thing; // Fail. 

int main(void){ 
    // Code goes here. 
} 

ただし、次のコードは機能します。

typedef struct { 
    char *desc; 
    unsigned quantity; 
} item; 

item *inventory[INVENTORY_SIZE]; 

item thing = { "This is a thing.", 2 }; 

int main(void){ 
    inventory[0] = &thing; // Works. 
} 

私は関数の外で関数を呼び出すことはできませんが、関数の外にグローバルを割り当てることができます。これは割り当てのように見えます。だからなぜそれは機能しないのですか?

編集:私が「投稿」をクリックするとすぐに、私は答えを実現したと思う。関数の外の宣言で値を代入することはできますが、それが宣言である場合に限ります。それは答えですね。

+0

*割り当て*と*初期化*の違いを誤解していると思います。あなたのものは元のものです。それはあなたがやっていることをやっているところであれば後者になることができます。あなたが望むことを実行することは可能ですが、初期化としてのみ、いくつかのコードを再配置し、ポインタ配列に初期化シーケンスを与える必要があります。 – WhozCraig

+0

あなたの編集を(私の答えと併せて読まれると) "関数の外の宣言で値を代入"しないで、その宣言の一部としてオブジェクトを初期化します。あなたはそれがアサインメントのように見えることは間違いありませんが、それが* :-)ではないというぎりぎりの事実を除いて – paxdiablo

答えて

1
item thing = { "This is a thing.", 2 }; 

は、どのように見えるかもしれませんが割り当てられていません。実際にはの初期化(宣言の一部)が機能の外で完全に有効です。

一方、

inventory[0] = &thing; 

は、いくつかの説明の関数内でなければならない割り当てです。

結論として、割り当てに初期化ルールを適用しないでください。

0

まず、

item thing = { "This is a thing.", 2 } 

は特殊なケースではなく、割り当てである、initializationあります。これは、変数の初期値を設定します。初期化は宣言と結合されているため、ファイルスコープ内に存在することができます。

assignment expressionは、関数内にのみ存在できます。簡単な言葉で言えば、割り当ては実行時に実行する必要があるため、関数スコープ内になければを実行するとを知る方法がありません。

0

あなたは正しいと思います.2番目の例は、文の実行ではなく初期化です。グローバル変数は、プログラムの実行前に作成されるため(すなわち、main関数への最初の呼び出し)、これは正当です。コマンドフローはmain関数から始まり、プログラムのコードで呼び出されるときに呼び出されるすべての関数に入ります。だから、プログラムはある機能の中にあり、ある機能の中にいないコマンド(あらかじめ行われている初期化に加えて)は、自動的にデッドコードになります---プログラムはそれらに到達する手段がありません。それはあなたが達成しようとしているものならば

1

これは、動作するはずです:

item thing = { "This is a thing.", 2 }; 
item *inventory[INVENTORY_SIZE] = {&thing}; 

これらはdefinitions(彼らはトップレベルのスコープであるため)ので、コンパイラは先に行くと、それらのためのストレージを割り当てますこの翻訳単位。

5

我々は書く:

data_type variableName = someValue; 

それは我々が最初の変数であることをvariableNameにを宣言している、とタイプDATA_TYPEの意味。その後、値の割り当てが直後に実行されており、variableNameに割り当てられた最初の値であるため、someValueにも初期化されます。

これは許可されています。これは特別なタイプの関数であり、初期化と呼ばれるシステム関数です。

しかし

variableName = someValue; 

を書くことは、我々は任意の関数のスコープ外someValueのにvariableNameにを割り当てるしようとすると、初期化の範囲外であることを意味します。

これは機能外ではできません。

コードは、初期割り当て時に発生する初期化を除いて、呼び出された関数内からのみ実行されます。

関連する問題