2

extern キーワードを使用して実装ファイル内の静的変数を参照するコードを実行すると、奇妙なことがわかります。そこで、実装ファイル内で静的変数 gCounter を宣言し、同じ実装ファイル内の 2 つのメソッド内でそれを参照します (静的であるため)。ただし、メソッドで extern キーワードを使用すると、異なる結果が得られます。私の理解 (私の本を読むことから) は、メソッドと同じファイルで宣言された静的変数を参照している場合、 extern は必要ないということです。コードは次のとおりです。

/** インターフェース **/

#import <Foundation/Foundation.h>

@interface Fraction : NSObject

+(Fraction *) allocF;
+(int) count;

@end

/**implementation**/

#import "Fraction.h"

static int gCounter;

@implementation Fraction

+(Fraction *) allocF
{
    extern int gCounter;
    ++gCounter;

    return [Fraction alloc];
}

+(int)count
{
    extern int gCounter;
    return gCounter;

 }

@end

/**main**/
#import "Fraction.h"

int main (int argc, const char * argv[])
{

    @autoreleasepool
    {

    Fraction *a, *b, *c;

    NSLog(@"The number of fractions allocated: %i", [Fraction count]);

    a = [[Fraction allocF] init];

    b = [[Fraction allocF] init];

    c = [[Fraction allocF] init];


    NSLog(@"The number of fractions allocated: %i", [Fraction count]);

    }

    return(0);

}

メソッドで extern キーワードを使用すると、コードは正しく機能し、整数 3 が出力されます。ただし、 extern を削除すると、整数 2 が出力されます。何故ですか?gCounter は静的変数なので、これは extern キーワードなしで機能するべきではありませんか?

4

1 に答える 1

3

declarationaと aの違いを理解する必要がありますdefinition

  • static int xint xは定義です。コンパイラは、x.
  • extern int x一方、宣言です。x別の場所で定義されている変数があることをコンパイラに伝えます。

また、同じ変数名を持つ異なるスコープで異なる変数を定義できます。

int x = 0;
{
    int x = 1;
    NSLog(@"x = %d", x); // x = 1
}
NSLog(@"x = %d", x); // x = 0

だからあなたが書くなら

int x;
void foo() {
    int x;
    x++;
}

関数 local をインクリメントしていますx

int x;
void foo() {
    x++;
}

グローバルをインクリメントしますx

int x;
void foo() {
    extern int x;
    x++;
}

extern int xの定義が別のコンパイル単位にあるかどうかを宣言する必要がありますx。同じコンパイル単位にある場合、最後の 2 つは同等です。

于 2013-08-06T03:06:43.900 に答える