static、const、extern关键字的作用

887 阅读3分钟

 static关键字

修饰局部变量时:

1、使得局部变量只初始化一次

2、局部变量在程序中只有一份内存

3、局部变量作用域不变,但是生命周期改变了(程序结束才能销毁)

修饰全局变量

1、全局变量的作用域仅限当前文件,外部类是不可以访问到该全局变量的。

默认情况下,全局变量在整个程序中是可以被访问的(即全局变量的作用域是整个项目文件,不导入头文件)

#import "ViewController.h"
 
static NSString *staticValue2;
 
@interface ViewController ()
 
@end
 
@implementation ViewController
 
- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 连续调用两次
    [self staticTestA];
    [self staticTestA];
    
    // 连续调用两次
    [self staticTestB];
    [self staticTestB];
    
    // 连续调用两次
    [self staticTestC];
    [self staticTestC];
}
 
- (void)staticTestA {
    static NSString *staticValue1;
    NSLog(@"staticTestA------------%p", &staticValue1);
}
 
- (void)staticTestB {
    static int i = 0;
    i++;
    
    NSLog(@"staticTestB------------%d", i);
}
 
- (void)staticTestC {
    int i = 0;
    i++;
    
    NSLog(@"staticTestC------------%d", i);
}
 
 
@end

打印结果: 

2017-12-08 17:25:51.862511+0800 Test[28720:12325782] staticTestA------------0x10f123148 

2017-12-08 17:25:51.862617+0800 Test[28720:12325782] staticTestA------------0x10f123148 

2017-12-08 17:25:51.862712+0800 Test[28720:12325782] staticTestB------------1 

2017-12-08 17:25:51.862785+0800 Test[28720:12325782] staticTestB------------2 

2017-12-08 17:25:51.862865+0800 Test[28720:12325782] staticTestC------------1 

2017-12-08 17:25:51.862947+0800 Test[28720:12325782] staticTestC------------1 


const关键字 被const修饰的变量是只读的

基本数据类型,

int const a = 10; 和const int b = 20; 效果是一样的 只读常量

指针类型

NSString *p;

*p是地址中的值,p是指针地址。

NSString const *p 表示地址中的值没法改变,但是指针的指向可以改变; 

而 NSString *const p 表示指针的指向不能改变,但是地址里的内容是可以改变的


extern 外部常量的最佳方法

extern const 关键字,表示这个变量已经声明,只是引用,且不可修改。


小结:1:.m文件中定义的常量,用const修饰代表常量。其中const CGFloat a = 10.f; 和 CGFloat const a = 10.f;两种写法是一样的,都代表a值为常量,不可修改,但是外部可通过extern CGFloat a;引用该变量,若无const,则通过extern引用a后也可修改。全局变量若只想被该文件所持有,不希望被外界引用,则用static修饰,也就是static const CGFloat a = 10.f;和 static CGFloat const a = 10.f;是一样的,注意只有全局变量用static修饰时,才只被该文件所持有,外界不可引用。

const CGFloat XMGRed = 0.4;定义一个常量,若是全局变量,则可被外界引用,但不能修改

2:定义不可变字符串时:用 static NSString * const name = @"JACK";则指针name不可变,外界不可以给该变量赋值。其中const修饰可变与不可变,就看const右边修饰的是什么 例如:NSString * const name = @"JACK",则代表指针name不可变,*name可变,若NSString const * name = @"JACK",则 *name不可变,指针name可变

3:UIKIT_EXTERN:其实就是extern,最好加上const,来告诉外界这个引用变量不可改变。

UIKIT_EXTERN const CGFloat XMGRed;

4:宏定义 与 static const 修饰的全局常量的区别:一般项目中尽量避免使用大量的宏定义,因为每一个宏定义都会在内存中临时开辟一份内存空间,而static const 修饰的常量 ,则只会开启一份内存空间,其使用效果和宏定义相同,建议以后项目开发中定义常量时,多用 static const 来代替宏定义