美文网首页IOS开发基础(oc)
ios开发基础学习笔记(五)--static、const和ext

ios开发基础学习笔记(五)--static、const和ext

作者: miloluo | 来源:发表于2018-05-14 00:15 被阅读0次

    前言

    大家好,我是milo,在学习ios开发中,我们有时候会用到static(静态变量)、const(常数)、extern(外部变量),在这篇文章中,我将讲解它们的基本使用。我讲解的顺序是extern->static->const,为什么有个顺序呢,那么请往下看。

    extern

    全局变量extern,也称之为外部变量,是在方法外部定义的变量。它不属于哪个方法,而是属于整个源程序。作用域是整个源程序。如果全局变量和局部变量重名,则在局部变量作用域内,全局变量被屏蔽,不起作用。

    上面这段话理解起来有点抽象,下面演示一个简单的例子:

    JJExtern.h文件
    #import <Foundation/Foundation.h>
    
    NSString *flag = @"JJExtension";
    
    @interface JJExtern : NSObject
    
    @end
    

    定义了一个字符串flag

    main.m文件
    #import <Foundation/Foundation.h>
    int main(int argc, const char * argv[]) {
    
        extern NSString *flag;
        
        NSLog(@"%@",flag);
        
        return 0;
    }
    
    

    打印结果如下:
    2018-05-12 16:46:01.643949+0800 oc练习[1810:181852] JJExtension

    从以上例子可以看出,main.m无需导入JJExtern的头文件,直接在 NSString *flag前面加上extern就可以取得JJExtern内的flag值。需要注意的是,extern修饰的变量名必须是和JJEXtern下变量名的一致的,即都为flag,否则就会提示找不到。还有一点要注意的是,extern修饰的变量是没有真正的内存的。

    总结:
    <1>要想访问全局变量可以在前面加extern
    <2>extern修饰的变量没有真正内存

    那么问题来了,即然只需要extern就能得到并修改其他文件的变量,此不是很安全?因为随时会被人改掉?该怎么办?
    答案就是使用static修饰变量,那么该变量就只能在本文件中修改,其他文件无法使用extern获取变量。

    static

    static既可修饰全局变量,又可以修饰局部变量。

    1、修饰全局变量

    以前面的例子来说,在 JJExtern 的 NSString *flag = @"JJExtension"; 前面加static,如下:

    #import <Foundation/Foundation.h>
    
    static NSString *flag = @"JJExtension";
    
    @interface JJExtern : NSObject
    
    @end
    
    

    再次运行main.m,编译器报错如下图

    static修饰后extern就找不到flag.png 所以只要在全局变量前加static,那么这个全局变量的作用域就会缩小到当前文件,外界就不能访问了。
    总结:static修饰全局变量,保证全局变量安全,外界不可访问与修改,作用域仅限于当前文件。

    2、修饰局部变量

    下面先看示例代码:

    main.m文件
    void test()
    {
        static int a = 0;
        a++;
        NSLog(@"a = %d", a);
    }
    
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
    
             for (int i = 0; i<3; i++) {
               test();
           }
    
        }
        return 0;
    }
    

    修饰局部变量时,作用域仅限于test函数的大括号,其他地方都不顶用 。test这个函数中如果不加static,那么a打印出来的结果永远是1,因为每当调用一次函数,就会定义一个新的变量,每次a的值都是零,a++后就是1 。

    但是加上static后,含义就不一样了,打印的结果就是1,2,3......因为被static修饰的变量只会初始化一次,永远都只有一份内存,所以当第一次调用test函数时,a有一个内存空间,并且值是0,第二次再调用test函数时由于int a被 static 修饰,所以不会再初始化新值,它会拿到之前的那份内存a++,就会变为1,以此类推,之后就会变为2,3,4......

    总结:
    <1>让局部变量只初始化一次
    <2>局部变量在程序中只有一份内存
    <3>保住所修饰变量的命,保证它不会挂,直到程序结束,这个局部变量才会销毁

    const

    一句话概括,const的作用就是使其右边的变量(包括指针变量),只为可读,不可被修改。

    看完下面三段相似的代码,就可以理解const的用法了。

    int x = 1;  
    int y = 2;  
    const int *px = &x; // 让指针px指向变量x(此时const右边是*p)
    px = &y; // 改变指针px的指向,使其指向变量y  
    *px = 3; // 改变px指向的变量x的值,出错:Read-only variable is not assignable 
    
    int x = 1;  
    int y = 2;  
    int * const px = &x; // 让指针px指向变量x(此时const右边是p)
    px = &y;    // 改变px的指向,出错:Read-only variable is not assignable  
    (*px) += 2; // 改变px指向的变量x的值  
    
    int x = 1;  
    int y = 2;  
    const int * const px = &x; // 让指针px指向变量x(此时const右边是*p和p)
    px = &y;    // 改变px的指向,出错:Read-only variable is not assignable  
    (*px) += 2; // 改变px指向的变量x的值,出错:Read-only variable is not assignable  
    

    上面三段代码处理的是基本数据类型,我们知道oc语言是c语言的超集,所以上面这部分基本数据类型的处理oc与c是一样的。
    但是我们知道oc是c语言的超集,oc中还有着NSString等的数据类型,它们的本质是个结构体,所以在处理指针方面与基本数据类型不同。

    下面通过一小段代码感受一下:

    #import <Foundation/Foundation.h>
    int main(int argc, const char * argv[]) {
    
        NSString const * name = @"milo";//  const修饰*name
        NSLog(@"%@",name);// 打印“milo”
        
        name = @"vicky";// 在oc中NSString等类的值不是通过*name访问的,而是通过name访问的,这就是和c语言的指针的区别,但还是遵循const右边是谁,谁就只可读的原则。
        NSLog(@"%@",name);//  打印“vicky”
    
    }
    

    想深入了解可以参考http://www.cocoachina.com/bbs/read.php?tid=1708764
    https://www.cnblogs.com/lulipro/p/7460206.html,分别是oc指针讨论和c指针详解。

    引用了以下链接的资料,在此表示感谢:
    http://www.cocoachina.com/bbs/read.php?tid=1708764
    https://blog.csdn.net/jymn_chen/article/details/18900201
    https://www.cnblogs.com/lulipro/p/7460206.html
    https://blog.csdn.net/gezi0630/article/details/51993934

    相关文章

      网友评论

        本文标题:ios开发基础学习笔记(五)--static、const和ext

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