IOS const static extern 深度解析

我想对于ios开发的人来讲这3个关键字一定都很熟悉,但是你真的都明白了吗?下面模拟一下面试。我们一层层的深入分析。

1.请你说一下const和宏的区别

首先,很多字符串我们都定义成宏,但是苹果推荐的是使用const。

区别:

1.编译时刻:const是编译阶段,define是预编译阶段

2.编译检查:由于宏是预编译阶段处理,宏不做检查,只是单纯的替换。 const是会编译检查, 可以报编译错误。

3.宏的优势:可以定义函数,方法。const不行

4.宏的劣势:大量宏,会造成编译时间久,每次都需要重新替换。

好了,记下来会继续深入问你const

2.那你看这段代码给我说一下两种写法哪个会有问题

答案是两种写法都是对的。都是定义一个常量b,如果对b修改会引起报错;

下面继续:

int a = 10;
  
int *const p = &a; 
int const  *p = &a; 
       
*p = 20; 
p = &b;

说一下这两种写法有什么区别:

如果const修饰的是p,那么p的值是不能改变的,也就是p中存放的a的地址无法改变(p是int类型的指针变量)。但是*p是可以变化的,我们并没有

用const去修饰*p,所以可以通过*p去改变a的值

如果const修饰的是*p,那么*p的值是不能改变也,也就是p中存放的a的地址中的值无法改变,但是p的值是可以改变的(也就是p此时可以改变指向)

3.那你跟我说下static吧,static是做什么用的。

static就是修饰变量的,可以延长局部变量的生命周期,从栈区拿到全局区。恭喜你,这样答分数很低。面试官会给你几个demo。看看你是否真的理解了static。其实static的作用是需要细分的。

  • 修饰局部变量:

    1.延长局部变量的生命周期,程序结束才会销毁。

    2.局部变量只会生成一份内存,只会初始化一次。

    3.改变局部变量的作用域。

  • 修饰全局变量

    1.只能在本文件中访问,修改全局变量的作用域,生命周期不会改

    2.避免重复定义全局变量

为了考察你的理解:会问你,那你说一下static在内存上怎么处理的。比如我现在有一个类,类中用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。这就考察了你是否真的理解static,首先,test里面试局部变量age。static的修饰只是延长了局部变量的生命周期。从栈区拿到了全局区。所以第一次输出1,第二次输出2,每次+1。最后一个行输出考察了extern,其实就是获取本文件的全局变量,后面我们会细说。所以这里全局变量定义了10,就输出10,而没有输出局部变量2.

好了,继续深入问:

.m中

const NSString *HSCoder = @"hello word";

另一个类的.m中

    extern NSString *HSCoder;
    NSLog(@"%@",HSCoder);

问你可以输出吗?hello word吗?

.m中

NSString  *const nameKey = @"name"

.h中

extern NSString * const nameKey;

另一个类的.m中

 NSLog(@"%@",nameKey);

问你可以输出name吗?

答案是都可以。这就是extern的用法

  • extern作用:
    • 只是用来获取全局变量(包括全局静态变量)的值,不能用于定义变量
  • extern工作原理:
    • 先在当前文件查找有没有全局变量,没有找到,才会去其他文件查找。

好了,继续问。如果将全局常量,加上static修饰,上面的代码会输出什么

static const NSString *HSCoder = @"hello word";

这里又考到了static的作用,千万不要想成什么延长生命周期,继续累加等等。。。注意到static的作用分为两方面。这里问的是修饰全局的。不改变生命周期,单纯的修改作用域。让这个常量只能在当前.m使用。所以,这段代码编译会报错

猜你喜欢

转载自blog.csdn.net/lee727n/article/details/80196045