外部变量
如果在Objective-C程序的开始处(所有方法、类定义和函数定义之外)编写以下语句:
int gMoveNumber = 0;
那么这个模块中的任何位置都可以引用这个变量的值。在这种情况下,我们说gMoveNumber被定义为全局变量。为了向阅读程序的人说明变量的作用域,按照惯例,用小写的g作为全局变量的首字母。
实际上,在Objective-C中,这样的定义使得其他文件也可以访问变量gMoveNumber的值。确切地说,前面语句不仅将gMoveNumber定义为全局变量,而且将其定义为外部全局变量。
外部变量是可被其他任何方法或函数访问和更改其值的变量。在需要访问外部变量的模块中,变量声明和普通方式一样,只是需要在声明前加上关键字extern。这就告知系统,要访问其他文件中定义的全局变量。下面这个例子说明如何将gMoveNumber声明为外部变量:
extern int gMoveNumber;
现在,包含前面这个声明的模块就可以访问和改变gMoveNumber的值。同样,通过在文件中使用类似的extern声明,其他模块也可以访问gMoveNumber的值。
使用外部变量时,必须遵循下面这条重要原则:变量必须定义在源文件中的某个位置。这是通过在所有方法和函数外部声明变量,并且前面不加关键字extern,如下所示:
int gMoveNumber;
这里,前面显示过,可以为这个变量指派初始值。
定义外部变量的第二种方式是在所有函数之外声明变量,在声明前面加上关键字extern,同时显式地为变量指派初始值,如下所示:
extern int gMoveNumber = 0;
然而,这并不是首选的方法。编译器将给出警告消息:提示你已将变量声明为extern的,并同时为变量赋值。这是因为使用关键字extern的表明这条语句是变量的声明而不是定义。记住,声明不会引起分配变量的存储空间,而定义会引起变量存储空间的分配。因此,前面的例子强行将声明当作定义处理(通过指派初始值),所以违背了这个规则。
处理外部变量时,变量可以在许多地方声明为extern,但是只能定义一次。
通过观察一个小程序例子来说明外部变量的用法。假设我们定义了一个名为Foo的类,并将以下代码键入一个名为main.m的文件中:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#import “Foo.h” int gGlobalVar = 5; int main ( int argc, char *argc[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Foo *myFoo = [[Foo alloc] init]; NSLog (@”%i “, gGlobalVar); [myFoo setgGlobalVar: 100] NSLog (@”%i”, gGlobalVar); [myFoo release]; [pool drain]; return 0; } |
在前面的程序中,gGlobalVar定义为全局变量,因此任何方法〔或函数)只要正确地使用extern声明,都可以访问它。假设Foo方法setgGlobalVar:如下所示:
1
2
3
4
5
|
-( void ) setgGlobalVar: ( int ) val { extern int gGlobalVar; gGlobalVar = val; } |
该程序将在终端生成以下结果:
1
2
|
5 100 |
这就证明了方法setgGlobalVar:可以访问和改变外部变量gGlobalVar的值。
如果有很多方法需要访问gGlobalVar的值,只在文件的开始进行一次extern声明将比较简便。但是如果只有一个或少数几个方法要访问这个变量,就应该在其中每个方法中单独进行extern声明。这样将使程序的组织结构更清晰,并且使实际使用变量的不同函数单独使用这个变量。注意,如果变量定义在包含访问该变量的文件中。那么不需要单独的extern声明。