首先定义全局变量和局部变量 如下
#import <Foundation/Foundation.h>
#import "Scope.h"
int gGlobalVar=300;
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSLog(@"%i",gGlobalVar);
int gGlobalVar=400;
NSLog(@"%i",gGlobalVar);
}
return 0;
}
2015-04-01 14:52:12.123 Extern[1924:303] 300
2015-04-01 14:52:12.125 Extern[1924:303] 400
从结果可以看出在没有定义局部变量之前 程序中显示的是全局变量的gGlobalVar 当定义了新的局部变量gGlobalVar后 全局变量被局部变量覆盖了 程序中显示的是局部变量的gGlobalVar 这是两个不同的gGlobalVar 全局变量存放在静态存储区 局部变量存放在栈
再看外部全局变量 如下
#import <Foundation/Foundation.h>
int gGlobalVar=100;
@interface Scope : NSObject
-(void) setgGlobalVar:(int)g;
-(int) gGlobalVar;
@end
#import <Foundation/Foundation.h>
#import "Scope.h"
//int gGlobalVar=300;
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSLog(@"%i",gGlobalVar);
int gGlobalVar=400;
NSLog(@"%i",gGlobalVar);
}
return 0;
}
这里在头文件中定义全局变量gGlobalVar 编译器会报错 重复定义变量 这里就要说到#import了 #import是预处理程序的一种 功能是导入文件 就像是文件直接插入到#import语句所在的位置 由于头文件要被其他文件导入 就不可避免会重复定义 所以一般情况之下 头文件里只能声明 不能定义 修改一下 如下
#import <Foundation/Foundation.h>
int gGlobalVar;
@interface Scope : NSObject
-(void) setgGlobalVar:(int)g;
-(int) gGlobalVar;
@end
#import <Foundation/Foundation.h>
#import "Scope.h"
//int gGlobalVar=300;
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSLog(@"%i",gGlobalVar);
gGlobalVar=100;
NSLog(@"%i",gGlobalVar);
int gGlobalVar=400;
NSLog(@"%i",gGlobalVar);
}
return 0;
}
2015-04-01 16:05:06.336 Scope[2405:303] 0
2015-04-01 16:05:06.339 Scope[2405:303] 100
2015-04-01 16:05:06.341 Scope[2405:303] 400
这里再用extern关键字声明外部全局变量也会报错 显示外部全局变量被局部变量覆盖了 因为使用extern就相当于把外部全局变量视作局部变量处理 两个局部变量显然报错 这里要访问全局变量gGlobalVar可以使用方法 如下
#import "Scope.h"
//int gGlobalVar=200;
@implementation Scope
-(void) setgGlobalVar:(int)g
{
gGlobalVar=g;
}
-(int) gGlobalVar
{
return gGlobalVar;
}
@end
#import <Foundation/Foundation.h>
#import "Scope.h"
//int gGlobalVar=300;
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSLog(@"%i",gGlobalVar);
gGlobalVar=100;
NSLog(@"%i",gGlobalVar);
int gGlobalVar=400;
NSLog(@"%i",gGlobalVar);
// extern int gGlobalVar;
// NSLog(@"%i",gGlobalVar);
Scope *sco=[[Scope alloc] init];
NSLog(@"%i",sco.gGlobalVar);
}
return 0;
}
2015-04-01 16:27:36.858 Scope[2502:303] 02015-04-01 16:27:36.861 Scope[2502:303] 1002015-04-01 16:27:36.865 Scope[2502:303] 4002015-04-01 16:27:36.866 Scope[2502:303] 100
这样就可以访问被覆盖的全局变量gGlobalVar 调用方法 方法之中有全局变量gGlobalVar但是我们一般都在实现文件中去定义全局变量 如下
#import "Scope.h"
int gGlobalVar=200;
@implementation Scope
-(void) setgGlobalVar:(int)g
{
gGlobalVar=g;
}
-(int) gGlobalVar
{
return gGlobalVar;
}
@end
#import <Foundation/Foundation.h>
#import "Scope.h"
//int gGlobalVar=300;
int main(int argc, const char * argv[])
{
@autoreleasepool {
extern int gGlobalVar;
NSLog(@"%i",gGlobalVar);
gGlobalVar=100;
NSLog(@"%i",gGlobalVar);
// int gGlobalVar=400;
// NSLog(@"%i",gGlobalVar);
Scope *sco=[[Scope alloc] init];
NSLog(@"%i",sco.gGlobalVar);
}
return 0;
}
2015-04-01 17:28:15.448 Scope[2767:303] 200
2015-04-01 17:28:15.450 Scope[2767:303] 100
2015-04-01 17:28:15.451 Scope[2767:303] 100
这里声明局部变量gGlobalVar编译器也会报错 因为extern已经将外部全局变量视作局部变量 由于这样的全局变量可以被其他文件访问 破坏了数据封装的原则 所以一般使用静态变量 如下
#import "Scope.h"
static int gGlobalVar=200;
@implementation Scope
-(void) setgGlobalVar:(int)g
{
gGlobalVar=g;
}
-(int) gGlobalVar
{
return gGlobalVar;
}
@end
#import <Foundation/Foundation.h>
#import "Scope.h"
//int gGlobalVar=300;
int main(int argc, const char * argv[])
{
@autoreleasepool {
Scope *sco=[[Scope alloc] init];
NSLog(@"%i",sco.gGlobalVar);
sco.gGlobalVar=500;
NSLog(@"%i",sco.gGlobalVar);
}
return 0;
}
2015-04-01 18:39:19.266 Scope[3118:303] 200
2015-04-01 18:39:19.269 Scope[3118:303] 500
这里使用点运算符赋值 编译器有bug 显示没有方法setGGlobalVar 拜托 本来就没有setGGlobalVar 只能使用方法赋值 使用静态变量之后想要访问 只能通过方法 这样就符合了数据封装原则
关于静态变量
1、程序只分配一次内存 保留值
2、静态全局变量只在定义它的文件中有效
3、静态局部变量只在定义它的方法或函数中有效