3

読んでいるときに次の問題に遭遇しました...この背後にあるロジックを理解できません。

auto int c;
static int c;
register int c;
extern int c;

最初の 3 つが定義で、最後の 1 つが宣言であるとします。

4

5 に答える 5

4

の最後のものは、 のexternストレージを定義していませんc。がどこかに存在することを示すだけであり、リンカーはそれを別の場所で定義されたcグローバルに解決できるはずです。c

単一の .c ファイルをコンパイルしてリンクし、最後のファイルを使用しようとするとc、リンカー エラーが発生します。最初の 3秒では、現在のコンパイル単位に実体がある (定義されcている) ため、そうではありません。

extern宣言と定義について詳しく知りたい場合は、このトピックに関する優れた記事をご覧ください。その記事から引用するには:

変数/関数の宣言は、変数/関数がプログラムのどこかに存在することを単に宣言しますが、メモリはそれらに割り当てられません

于 2012-07-16T15:29:26.030 に答える
3

このキーワードexternは、変数 (またはおそらく関数) の定義が別の場所にあるという事実を参照します。次にコンパイラは、この宣言を別のファイル内の定義済み本体にリンクします。前の 3 つのキーワードは宣言を示します。変数は他の場所で定義されていないため、定義されていませんprototypes

たとえば、次のようなプロジェクト構造があるとします。

..
-- main.c
-- client.c
-- client.h
-- server.c
-- server.h

ヘッダー ファイルを使用してこれらをコンパイルするgccと、ヘッダー ファイルは通常define、プログラムに必要な変数になります。declarationこれにより、.c ファイル内のシンボルにリンクするシンボルが割り当てられます。これは、コンパイラがさまざまなプロジェクト ファイルを.oオブジェクトとリンクする方法です。objdump -dプログラムの実際の逆アセンブル構造をデバッグするために (Linux を使用していると仮定して) を使用すると、これらすべてがどのように表示されるかにさらに興味があるかもしれません。

楽しんで頑張ってください!

于 2012-07-16T15:29:43.773 に答える
2

最初の 3 つのステートメントは、実際にint.

最後のものはそうではありません。コンパイラに伝えるのは、別のコンパイル単位のどこかで、int呼び出されcた が定義されるということだけです。

定義されていない場合、後でリンカー エラーが発生します。当然のことながら、リンカはそれcが定義されていないと言うでしょう。

于 2012-07-16T15:29:52.133 に答える
2

4 つの文は宣言ですが、最初の 3 つの文は定義でもあります。

宣言と定義の違いについては、こちらをお読みください。

autostatic、およびregisterは、変数の修飾子です。それらに関するドキュメントを読んでください。

externは、変数または関数の定義が別の場所 (別のCモジュール内) にあることをコンパイラーに伝えているため、宣言のみです。

それが役に立てば幸い!

于 2012-07-16T15:30:06.067 に答える
2

最初の 3 つは、変数用のストレージを確保するための定義です。

最後の 1 つは のストレージを割り当てませんint c。他の場所で割り当てられ、名前が付けられたストレージを使用するだけです。

于 2012-07-16T15:30:39.450 に答える