23

さて、「少し古い」本(「Cプログラミング言語」、第2版、デニス・リッチー著)を読んで、私は次のように交差しました:

外部変数は、関数の外部で1回だけ定義する必要があります。これにより、ストレージが確保されます。変数は、それにアクセスする各関数でも宣言する必要があります

そして、私は-何のようでしたか?

「変数は、それにアクセスしたい各関数でも宣言する必要があります」。それから、私はもう一度ショックを受けました:

int max; 
/* ... */
int main()
{
    extern int max;
    /* ... */
}

そしてもう1つ-何?!


私の知る限り(明らかに、それはそれほど多くはなく、十分ではありません)、externどこかでグローバル変数を定義し、別のファイルを介してそれにアクセスしたい場合にのみ意味があります(再度定義しないでください)。

それで:

  • または他の関数の中extern int max これのポイントは何ですか?main
  • 標準は、これが必須であると本当に言っていますか(この例では、それを使用する各関数でこの最大値を宣言する必要がありますか?)
  • これはC++でも同じですか(それがC ++タグを配置した理由です)?こんなものを見るのは初めてです。

注:これは、関数内で静的変数をexternとして宣言する使用法と同じではありませんか?

4

4 に答える 4

14

あなたの投稿は私を驚かせました。私はそのことを思い出せず、ずっと前にK&Rを読んだことがあります。私はここに初版しか持っていません、そしてそれもそこにあります。しかし、それだけではありません。初版から:

変数は、それにアクセスする各関数でも宣言する必要があります。これは、明示的なextern宣言によって、または暗黙的にコンテキストによって実行できます。

「コンテキストによって暗黙的に」に注意してください。本文の後半:

...変数の外部定義が特定の関数で使用される前にソースファイルで発生する場合、関数でextern宣言を行う必要はありません。したがって、main、...のextern宣言は冗長です。実際、一般的な方法は、すべての外部変数の定義をソースファイルの先頭に配置してから、すべてのextern宣言を省略することです。

つまり、extern変数を表示することは、その関数の関数内で実行することも、ソースファイルでそれに続くすべての関数の関数の外部で実行することもできます。これは、関数内で行われる本の中で唯一の場所であると私は信じています。後で、ファイルアプローチに使い慣れたものを使用します。

于 2012-08-30T15:43:37.877 に答える
11

extern int max内部mainまたは関数はコンパイラに「私はメインまたは関数内のローカル変数ではなく、他の場所で定義されたグローバル変数です」と言っています。

グローバルが同じファイルで宣言されている場合、役に立ちません。別のファイルでは、はい、ただし各関数ではなく、このグローバル変数を使用するソースのヘッドファイルで一度だけ宣言します。これはで同じですc++

于 2012-08-30T15:18:32.880 に答える
2

リンケージexternです。_ これは、この名前が、おそらく他のファイルにある他の名前にリンクされていることを意味します。(つまり、オブジェクトモジュールをリンクして実行可能ファイルを作成すると、この名前へのリンクされたすべての参照が同じオブジェクトを参照するようになります。)max

この宣言のスコープは、それが含まれる関数本体の残りの部分です。つまり、このファイル内の他の関数は、この宣言によって宣言された名前を認識しません(自分で宣言しない限り)。

スコープとリンケージは別物です。

于 2012-08-30T15:06:42.437 に答える
0

extern関数内で考えられるもう1つの理由は、ローカル変数がグローバル変数をシャドウイングしていないことを確認することです。

なしextern

int max = 33;
int main()
{
    int max; 
    printf("%d", max); // prints indeterminate value (garbage)
}

extern

int main()
{
    extern int max; 
    int max;
    printf("%d", max);
}

出力:

エラー:リンケージのない「max」の再宣言

于 2022-02-15T11:36:49.627 に答える