当我运行一些使用extern关键字引用实现文件中的静态变量的代码时,我看到了一些奇怪的东西。所以我在我的实现文件中声明了静态变量gCounter,并在同一个实现文件中的两个方法中引用它(因为它是静态的)。但是,当我在我的方法中使用extern关键字时,我会得到不同的结果。我的理解(从阅读我的书)是当你引用与你的方法在同一文件中声明的静态变量时,extern是不必要的。代码如下:
/ ** interface ** /
#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关键字,这不应该工作吗?
答案 0 :(得分:3)
您需要了解declaration
和definition
:
static int x
和int 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
,后两个是等效的。