OC中的 全局变量、局部变量、静态全局变量、静态局部变量

将从存储方式生命周期(时间)作用域(空间) 三个维度来区分它们。

1 存储方式

  • 静态存储方式
    静态存储方式是 程序一开始运行时就分配存储空间,从程序开始运行到程序结束,存储空间都保持不变的存储方式。
  • 动态存储方式
    动态存储是 程序在运行时,需要使用时才分配存储空间,不需要使用时立即释放的存储方式。不像静态存储,还未使用的时候就分配,程序结束才收回。

2 进程的内存分区

RAMZones.png
  • 代码区
    存放代码,只读防止运行时被修改。

  • 常量区

  • 全局(静态)区

    • 数据区
      静态存储方式下,变量被分配的空间,放在这里的变量已经初始化。
    • BSS
      同数据区相同,只不过放在这里的变量还没有初始化。

  • 动态存储方式下,变量被分配的空间,它大小并不固定,可动态扩张或缩减。当进程调用alloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用realse释放内存时,被释放的内存从堆中被剔除(堆被缩减)。放在这里的变量需要程序员手动管理(ARC本质上还是属于手动管理)。


  • 动态存储方式下,变量被分配的空间,此时变量由操作系统和编译器管理。并不需要人为管理。

3 全局变量 局部变量

C语言中的定义:全局变量是申明在函数之外的变量,局部变量是申明在函数内部,以及函数的形式参数的变量

  • 全局变量

    • 存储方式:静态存储,存储在全局(静态)区
    • 生命周期:静态存储方式决定了其生命周期为 从程序开始运行到程序结束
    • 作用域:该程序的所有文件。
  • 局部变量

    • 存储方式:动态存储, 存储在堆(对象类型)或栈(数据类型)中
    • 生命周期:动态存储方式决定了其生命周期为 变量使用期间
    • 作用域:方法和函数内,确切的说从申明到遇到 ‘}‘ 为止。
#import "ViewController.h"

int age = 24;//全局初始化区(数据区)

NSString *name;//全局未初始化区(BSS区)

@implementation ViewController

- (void)viewDidLoad {
 
    [super viewDidLoad];

    int tmpAge;//栈
 
    NSString *number = @"123456"; //123456\0在常量区,*number在栈上。
    
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:1];//分配而来的8字节的区域就在堆中,*array在栈中,指向堆区的地址
    
    NSInteger total = [self getTotalNumber:1 number2:1];
}

- (NSInteger)getTotalNumber:(NSInteger)number1 number2:(NSInteger)number2{

    return number1 + number2;//number1和number2 栈区
}

@end

4 全局变量 静态全局变量

全局变量在第3部分已经说明,静态全局变量就是在全局变量的前面加上 static 关键字。
由 static 修饰的 静态全局变量和全局变量的存储方式生命周期是相同的。但是它们的作用域是不同的,全局变量在所有文件中都可以访问到,而静态全局变量只能在其申明的文件中才能访问到。也就是说,static改变了全局变量的作用域,从而达到对其他文件隐藏变量的目的,这是static的第一个作用。

  • 静态全局变量
    • 存储方式:静态存储,存储在全局(静态)区
    • 生命周期:静态存储方式决定了其生命周期为 从程序开始运行到程序结束
    • 作用域:只有申明该变量的文件才可以访问到。
#import "ViewController.h"

NSSting *name = @"jake"  //全局变量,在其他文件中通过 extern 关键字 可以访问到。

static NSSting *nikeNmae = @"jeek" //静态全局变量,只可以在本文件中访问到。

@implementation ViewController

- (void)viewDidLoad {
 
    [super viewDidLoad];
}

@end

5 局部变量 静态局部变量

局部变量在第3部分已经说明,静态局部变量就是在局部变量的前面加上 static 关键字。
由 static 修饰的 静态局部变量和局部变量的作用域是相同的。但是它们的存储方式是不同的,存储方式的不同导致了它们的生命周期也是不同的。 也就是说static改变了局部变量的存储方式,从而达到保存变量的目的,这是static的第二个作用。

  • 静态局部变量
    • 存储方式:静态存储,存储在全局(静态)区
    • 生命周期:静态存储方式决定了其生命周期为 从程序开始运行到程序结束
    • 作用域:方法和函数内,确切的说从申明到遇到 ‘}‘ 为止。
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
   
    [super viewDidLoad];

    for (int i = 0; i < 5; i++) {
        
        [self textC];
    }
}

- (void)textC{
    
    NSUInteger localInt = 0;  //局部变量 
    
    static NSUInteger staticLocalInt = 0;  //静态局部变量
    
    NSLog(@"局部变量 = %lu,静态局部变量 = %lu",(unsigned long)localInt,(unsigned long)staticLocalInt);
    
    localInt++;
    
    staticLocalInt++;
}

// 运行结果
2017-06-25 21:31:30.583 ARC-Learn[11825:712288] 局部变量 = 0,静态局部变量 = 0
2017-06-25 21:31:30.584 ARC-Learn[11825:712288] 局部变量 = 0,静态局部变量 = 1
2017-06-25 21:31:30.584 ARC-Learn[11825:712288] 局部变量 = 0,静态局部变量 = 2
2017-06-25 21:31:30.584 ARC-Learn[11825:712288] 局部变量 = 0,静态局部变量 = 3
2017-06-25 21:31:30.584 ARC-Learn[11825:712288] 局部变量 = 0,静态局部变量 = 4

//局部变量是动态存储方式,调用textc()时,localInt分配内存,调用结束时立即收回内存,下次调用在重新分配内存。所以数据是无法保存的。  
//静态局部变量是静态存储方式,程序开始运行时,staticLocalInt分配内存,只分配这一次内存,也就是说只初始化一次,textc调用结束时并不收回,而是等到程序结束时才收回。

6 总结

想要比较透彻的理解 全局变量、静态全局变量、局部变量、静态局部变量是什么,以及它们的区别,一定要了解

  • 两中存储方式:静态存储动态存储
  • 存储方式的定义不难看出变量的存储方式决定其生命周期
  • 进程中的内存分区:代码区常量区全局(静态)区
  • 采用静态存储方式的变量存储在全局(静态)区,采用动态存储方式的变量存储在堆(对象类型)栈(数据类型、指针)
  • 局部变量和全局变量是根据它们申明的位置来区分的
  • 静态全局变量和静态局部变量分别是在全局变量和局部变量的基础上加上 static 关键字。
  • 全局变量、静态全局变量、静态局部变量采用静态存储方式,局部变量采用动态存储方式
  • 对于全局变量来说,static 改变了其作用域;对于局部变量来说,static改变了其存储方式,从而改变了生命周期。因此 static 这个说明符在不同的地方所起的作用是不同的。应予以注意。

7 参考

本文参考了以下博客,向原作者表示感谢!同时本人水平有限,如有错误还请指出,不甚感激!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容