每逢面试时多数会问到 const与宏的区别 及 static变量
先看下const与宏的区别:
- 编译时刻:宏是预编译(编译之前处理),const是编译阶段。
- 编译检查:宏不做检查,不会报编译错误,只是替换,const会编译检查,会报编译错误。
- 宏的好处:宏能定义一些函数,方法。 const不能。
- 宏的坏处:使用大量宏,容易造成编译时间久,每次都需要重新替换。
static局部变量和普通局部变量有什么区别
- 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。
- static局部变量只被初始化一次,下一次依据上一次结果值;
下面就看下const,static,extern定义和简单使用
一、关于const
1. const简述*
- const修饰的数据类型是指常类型,常类型的变量或对象的值是不能被更新的。它限定一个变量不允许被改变,产生静态作用。
const的作用和宏是很类似的,其实,苹果是不推荐我们使用宏的,它更喜欢我们使用const,在swift中宏就被抛弃了,我们只能使用const。
2. const有两个作用:
修饰右边的基本数据变量和指针变量;
被const修饰的变量只读,也就是只能获取,不能修改。
3. const的使用场景:
修饰全局变量 ==>全局只读变量 ==> 代替宏
修饰方法中的参数
二、关于static
static有两个作用:
-
- 修饰局部变量:
- 存储区由栈变为堆得静态存储区,生存期为整个源程序,可以延长生命周期,生命周期跟整个应用程序一致;
- 作用域仍为局部作用域, 只能在定义该变量的函数内使用。
- 只初始化一次, 只会分配一次内存。
-
- 修饰全局变量:
- 全局变量本来就是堆中的静态区, 生命周期没有改变
- 作用域会修改, 只能在当前文件下使用
- 好处就是: 不会被其他文件所访问,修改。其他文件中可以使用相同名字的变量,不会发生冲突。
三、关于extern
上面说到static修饰的全局静态变量,作用域是声明此变量所在的文件。而extern恰恰相反, extern修饰的全局变量默认是有外部链接的,作用域是整个工程,在一个文件内定义的全局变量,在另一个文件中,通过extern声明全局变量,就可以使用这个全局变量了。
1. extern简述
extern修饰全局变量的声明。以表示变量的定义在别的文件中。一般情况下默认,定义的全局变量都带有extern。
2. extern作用:
- 仅适于修饰全局变量,不能去修饰其他的变量
- 只是用来获取全局变量, 不能定义变量
- 置于变量前,以表示变量的定义在别的文件中。
- 就是说,我们在一个类中定义了全局变量
NSString *name = @"hello world!"
。但是想在别的类中使用这个全局变量, 无需引入头文件,只需要通过extern NSString *name;(并没有分配内存的)
,就可以获取到相应的全局变量进行后续操作。 -
注意
使用extern NSString *name;
获取的变量name的定义只能出现一次。
- 就是说,我们在一个类中定义了全局变量
3. extern工作原理:
- 先会去当前文件下查找有没有对应全局变量,如果没有,才会去其他文件查找。
所以注意:
任何情况下全局变量都是不安全的! 随时可能会被别人改掉。这是重点, 重点, 重点 ! ! !
四、实际应用
在项目开发中我常常这样用到
static NSString *kActivity = @"这是全局Activity";
static const NSString *encryDESkey = @"这是全局只读的秘钥12345678";
static const NSInteger kTextFeildTag = 07161547;
const CGFloat PAI = 3.14;
开发中常用static修饰全局变量, 只是改变作用域, 防止重复声明全局变量。但有些是不希望外界改动,只允许读取的, 就可以通过static与const联合使用达到目的。
static与const联合使用的作用:*
- 声明一个只读的静态全局变量
static const联合使用修饰变量和宏#define定义的比较
- 相同点
- 都不能再被修改, 一处修改,其它都改了
- 不同点
- static const修饰变量只有一份内存
- 宏定义,只是简单的替换,每次使用都需要创建一份内存
所以, 使用static const修饰更加高效,在同一个文件内可以使用static const取代#define
上面只是简单说了下const,static,extern关键字的作用及特点, 网上有很多关于这些的详细介绍, 也搜集了一些, 有兴趣研究的可以看看。
五. 关于static关键字的面试题
(来源于网络)
static全局变量与普通的全局变量有什么区别
- 全局变量(外部变量)的声明之前再冠以static 就构成了静态的全局变量。
- 全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。
- static全局变量只初使化一次,防止在其他文件单元中被引用;
区别在于:
非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
static局部变量和普通局部变量有什么区别
- 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。
- static局部变量只被初始化一次,下一次依据上一次结果值;
static函数与普通函数有什么区别 (C语言中)
- static函数与普通函数作用域不同,仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static修饰的函数),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件.
- static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
推荐链接:
const extern static 终极指南
如何正确使用const,static,extern
【如何正确使用const,static,extern】|那些人追的干货