2013-08-06 52 views
2

當我運行一些使用extern關鍵字引用實現文件中的靜態變量的代碼時,我看到了一些奇怪的東西。所以我在我的實現文件中聲明瞭靜態變量gCounter,並在同一個實現文件中的兩個方法中引用它(因爲它的靜態方法)。但是,當我在我的方法中使用extern關鍵字時,我得到了不同的結果。我的理解(從閱讀我的書)是,當您引用與您的方法相同的文件中聲明的靜態變量時,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關鍵字?

+1

當你刪除extern時,你是否刪除了整個聲明,還是把它作爲'int gCounter'? –

+0

@HotLicks我把它作爲int gCounter。 – Brosef

+0

擺脫gCounter;'行中的整個'extern。如果你的目標是引用靜態的'gCounter',你不需要它們。 – rmaddy

回答

3

您需要了解declarationdefinition之間的區別:

  • static int xint x的定義。編譯器爲x保留內存。
  • extern int x另一方面是一個聲明。你告訴編譯器,在其他地方定義了一個變量x。如果你寫

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

    你是遞增函數的局部x

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

    所以:

此外,您還可以定義不同的範圍不同的變量,即具有相同的變量名。

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

增加全球x

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

您需要聲明extern int x如果您的x定義是在另一個編譯單元,如果是在同一個編譯單元,最後兩個是等價的。

+0

感謝您的例子。我使用了本書中的同一個例子。在這個例子之後,這本書說:「回想一下,在兩個方法中不需要extern聲明,因爲gCounter變量是在文件中定義的。」那是怎麼回事? – Brosef

+0

'extern'聲明一個變量,該變量在不同的編譯單元中定義(例如一個不同的.m文件)。如果你定義一個全局變量並在同一個文件中使用它,編譯器會發現它是定義。 – Sebastian