const、static、extern的用法

来源:互联网 发布:weibull++软件下载 编辑:程序博客网 时间:2024/05/22 01:36



一、const 关键字


const 用来修饰其右边的变量,可以是基本数据类型变量或指针变量

1.基本数据类型

例如:

const int a = 10;

int const b = 10;

上面两种形式声明的常量都是只读的。


2.指针类型

例如:

const NSString *name  = @"xiaoming";

NSString const *name  = @"xiaoming";

NSString *const name  = @"xiaoming";//这个并不是修饰指针,还是修饰一个变量


以上三种形式的常量定义,前两种意思相同,const修饰的是一个指针(*name),表示的意思是:指针是一个常量,只读,不能修该其指向的地址;但是name的值可以修改,也就是你可以通过 name = @“zhangsan” 的形式修改。

第三种表示name是一个常量,只读,不允许修改其值。



二、static 关键字


1.static 修饰局部变量

1)保证局部变量只被初始化一次,在整个程序的运行中只有一份内存,延长该变量的生命周期;这时的局部变量在生命周期上类似全局变量,但是,变量的本身的作用域不变,不能在外部访问该静态变量。

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    

    int num = 1;

    num ++;

    NSLog(@"%d",num);

}

日志输出:

2017-09-0514:30:44.676 static_const_extern[30632:351713]2

2017-09-0514:30:44.837 static_const_extern[30632:351713]2

2017-09-0514:30:44.839 static_const_extern[30632:351713]2

2017-09-0514:30:45.061 static_const_extern[30632:351713]2

可以看出:每次touchesBegan方法执行结束后,变量num被释放,再次执行时有初始化该变量



- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    

    static int num =1;

    num ++;

    NSLog(@"%d",num);

}

日志输出:

2017-09-0514:31:57.063 static_const_extern[30658:352500]2

2017-09-0514:31:57.564 static_const_extern[30658:352500]3

2017-09-0514:31:58.068 static_const_extern[30658:352500]4

2017-09-0514:31:58.404 static_const_extern[30658:352500]5

由日志可以看出:

1> 静态变量确实只初始化一次,对基本数据类型默认初始化为0

2> 静态变量在touchesBegan方法结束后并未被释放,生命周期延长

3> 静态变量的作用域不变,因为此时还是不能再touchesBegan方法外部访问该静态变量


2.static 修饰全局变量

1)全局变量和静态全局变量的区别

1> 如果程序只有一个源文件,这两者没有区别

2> 如果有多个源文件,相同名称的全局变量只能有一个,即使在不同的源文件中也不能重名,否则编译报错!如果两者同时为静态全局变量,即使名称相同,也不会编译报错,必须同时为静态变量!!

代码:

#import <Foundation/Foundation.h>


NSString *address = @"beijing";


@interface FirstObj : NSObject


@end



#import <Foundation/Foundation.h>


NSString *address = @"beijing";


@interface SecondObj : NSObject


@end

以上是定义在.h文件中,对于.m文件也是一样,此时编译器会报 linker error

但是如果都用static修饰后,就不会出问题


2> 对于某个源文件中的全局变量,可以通过extern方式在其他文件使用,但是对静态全局变量,extern 也无效

代码:

#import "FirstObj.h"


NSString *address = @"beijing"//定义一个全局变量


@implementation FirstObj



@end


在其他文件中通过extern访问

#import "ViewController.h"


extern NSString *address;


@interface ViewController ()


@end


@implementation ViewController



- (void)viewDidLoad {

    [super viewDidLoad];

    

    NSLog(@"%@",address);//可以正常访问到address,不用引入头文件即可

}

但是如果把 FirstObj 中的address声明为静态全局变量,那么在其他文件中即使通过extern 也不能访问到。

注意:在头文件中定义的全局静态变量,如果在不同的文件中引用的话,他会初始化多次,在不同文件中引用的该变量不是同一个变量,地址是不同的。


三、extern 关键字


extern 关键字只是用来获取值的,不要用来定义变量。

extern NSString *address = @"123";//这样会有编译警告的

它的作用:声明一个外部变量,先在当前文件查找有没有全局变量,没有找到,才会去其他文件查找。


注意:extern不能和static组合使用,一个是外部链接,一个是内部链接,两者是冲突的




原创粉丝点击