美文网首页
static、const、extern

static、const、extern

作者: QYCD | 来源:发表于2021-03-31 17:54 被阅读0次

    生命周期: 一个变量能存活多久,什么时候分配内存,内存什么时候回收
    作用域: 一个变量在什么范围内是可见的,可用的

    static

    分为修饰局部变量和全局变量
    在函数或者代码块内声明的变量叫局部变量

    修饰局部变量:
    • 在程序中只有一份内存
    • 修改了局部变量的生命周期

    局部变量是存储在栈区的,其生命周期是整个代码块,作用域也是整个代码块,出了这个代码块,该变量的内存就会被回收,局部变量也被销毁。

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        NSInteger count = 0;
        count ++;
        NSLog(@"count: %ld", count);
    }
    
    多次点击屏幕,打印结果:
    [ViewController.m:40行] count: 1
    [ViewController.m:40行] count: 1
    [ViewController.m:40行] count: 1
    

    局部变量count是声明在touchesBegan:withEvent:方法的代码块内的,其生命周期和作用域均是该代码块。count初始化值为0,每执行一次结束后count就会被销毁,再次执行时 count又会被重新创建和在栈区申请内存

    当用static修饰局部变量时,变量被称为静态局部变量,静态局部变量和全局变量、静态全局变量一样存储在全局/静态存储区。存储在全局/静态存储区的变量其生命周期同程序生命周期,也就是直到程序结束它才会销毁。

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        static NSInteger count = 0;
        count ++;
        NSLog(@"count: %ld", count);
    }
    多次点击屏幕,打印结果:
    [ViewController.m:40行] count: 1
    [ViewController.m:40行] count: 2
    [ViewController.m:40行] count: 3
    

    首次点击屏幕,即执行函数体内代码时,由于static修饰局部变量count,在全局/静态区申请了一块内存,该内存生命周期同整个源程序,则下次执行该函数体内代码时,不会重新申请新的一块内存,而是找到这块叫count的内存,继续上一次结果进行计算。即使pop出当前VC(当前VC销毁),再次进入VC且点击屏幕执行,count的值仍会从之前值累加,因为static修饰了局部变量count,其生命周期同整个程序,不会随着当前VC的销毁而销毁

    修饰全局变量
    • 修改了全局变量的作用域,生命周期不会改变
    • 避免重复定义全局变量

    全局变量存储在全局/静态存储区,它的生命周期同整个源程序,直到程序结束才销毁,我们可以使用extern关键字来引用这个全局变量。

    如下我们可以使用extern关键字访问别的文件定义的全局变量(PS: IDE并不会自动补全)


    image.png image.png

    运行打印结果:


    image.png

    如果我们使用static修饰全局变量,则该变量作用域仅限于该文件


    const

    意为"常量、常数"

    const用来修饰右边的基本变量或指针变量,被const修饰的变量是只读的。

    如下图,变量a被const修饰,a是只读的,不能被修改


    image.png
    int const *p; //*p只读 p变量
    int * const p; //*p变量 p只读
    const int * const p; //p和*p都只读
    int const * const p; //p和*p都只读
    

    判断p和p是只读还是变量,关键看const在谁的前面,如果在p前面,那么p是只读,p还是变量,在p前面,那么p只读,p变量。

    const常用用法:
    定义一个全局只读变量,常和static一起使用,修改了其作用域,只在本文件内访问的只读变量
    static NSString *const kLogin = @"/login";
    

    extern

    在开发中,我们通常会单独抽一个类来管理一些全局的变量或常量
    比如:

    .h文件:
    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface Define : NSObject
    
    extern NSString * const kLoginNoti;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    .m文件:
    #import "Define.h"
    
    NSString *const kLoginNoti = @"notification.app.login";
    
    @implementation Define
    
    @end
    

    使用时,引入该文件#import "Define.h",则在该文件中即可使用定义的字段

    [[NSNotificationCenter defaultCenter] postNotificationName:kLoginNoti object:nil];
    

    const与宏的区别

    编译时刻: 宏是预编译(编译之前);const是编译阶段
    编译检查: 宏不做检查,不会报编译错误,只是替换;const会编译检查,会报编译错误
    宏的好处: 宏能定义函数、方法;const不能
    宏的弊端: 如果代码中大量的使用宏会使预编译时间变长

    PS: 定义一个字符串的宏,赋值给多个变量,打印其内存地址,经过测试: 宏定义的是常量,常量都放在常量区,只会生成一份内存,故网上说的是不对的

    #define SCREEN_Width    ([UIScreen mainScreen].bounds.size.width)
    #define SCREEN_Height   ([UIScreen mainScreen].bounds.size.height)
    

    参考:
    iOS中static,const,extern相关的问题
    IOS 关键字const 、static、extern详解
    iOS const、宏、static、extern的关系

    相关文章

      网友评论

          本文标题:static、const、extern

          本文链接:https://www.haomeiwen.com/subject/eiyhhltx.html