摘录:博主「MIKE-zi」
很多字符串我们都定义成宏,但是苹果推荐的是使用const。
区别:
1、编译时刻:const是
编译阶段
,define是预编译阶段
2、编译检查:由于宏是预编译阶段处理,宏不做检查
,只是单纯的替换。 const是会编译检查
, 可以报编译错误。
3、宏的优势:可以定义函数,方法。const不行
4、宏的劣势:大量宏,会造成编译时间久,每次都需要重新替换。
int a = 10; //&a:0x00007ffee741e008
int b = 30; //&b:0x00007ffee741e004
int *const p = &a; //p:0x00007ffee741e008
int const *p1 = &a; //p1:0x00007ffee741e008 *p1:10
*p = 20; //a:20 *p1:20
p1 = &b; //p1:0x00007ffee741e004 *p1:30
如果const
修饰的是p
,那么p的值是不能改变的
,也就是p中存放的a的地址无法改变
(p是int类型的指针变量)。
但是*p是可以变化的,我们并没有用const去修饰*p
,所以可以通过*p去改变a的值
如果const
修饰的是*p1
,那么*p1的值是不能改变的
,也就是p1中存放的a的地址中的值无法改变,但是p1的值是可以改变的
(也就是p1此时可以改变指向)
static修饰局部变量:
1、延长局部变量的生命周期,程序结束才会销毁。
2、局部变量只会生成一份内存,只会初始化一次。
3、改变局部变量的作用域。
static修饰全局变量
1、只能在本文件中访问,修改全局变量的作用域,生命周期不会改
2、避免重复定义全局变量
类中用static定义一个局部变量,每次执行这个static内存做了哪些事(从内存空间的角度)
-(void)method3:(NSMutableString *)str
{
static int n = 1;
// static等价语句
// if (变量n没有存储空间)
// {
// 给n分配存储空间
// }
[str appendFormat:@"%d ", n];
n++;
g1 = 400;
}
如同注释,将Int n 从栈区拿到全局区,延长n的生命周期到程序结束。
如果多次调用method3方法。
都会判断是否已经初始化了n,如果没有初始化,开辟内存空间,如果已经分配了,就把全局区的n,拿过来继续使用
// static修饰全局变量
static int age = 10;
- (void)test
{
// static修饰局部变量
static int age = 0;
age++;
NSLog(@"%d",age);
}
- (void)viewDidLoad {
[super viewDidLoad];
[self test];
[self test];
extern int age;
NSLog(@"%d",age);
}
输出结果: 1 , 2 ,10
test里面是局部变量age
。
static的修饰只是延长了局部变量的生命周期。从栈区拿到了全局区。
所以第一次输出1,第二次输出2,每次+1。
最后一个行输出考察了extern
,其实就是获取本文件的全局变量
,这里全局变量定义了10,就输出10,而没有输出局部变量2.
A.h中
static int age = 10;
A.m中
const NSString *HSCoder = @"hello word";
B.m中
extern NSString *HSCoder;
NSLog(@"%@",HSCoder);//hello word
extern int age;//不写也可以
NSLog(@"-----%d",age);//10
C.m中
NSString *const nameKey = @"name"
C.h中
extern NSString * const nameKey;
D.m中
NSLog(@"%@",nameKey);//name
答案是都可以。这就是extern的用法
`修饰全局的`。不改变生命周期,单纯的修改作用域。让这个常量只能在`当前.m使用`
static const NSString *HSCoder = @"hello word";
extern作用:
只是用来获取全局变量(包括全局静态变量)的值,不能用于定义变量
extern工作原理:
先在当前文件查找有没有全局变量,没有找到,才会去其他文件查找。
网友评论