您的位置:首页 > 移动开发 > IOS开发

【IOS 开发学习总结-OC-7.3】C 语言特性——动态存储与静态存储

2015-09-13 09:27 609 查看
从变量的存储机制来看,C 语言的变量可分为动态存储变量与静态存储变量。

变量按存储机制的分类

动态存储:程序在运行期间根据需要动态分配内存的存储方式。

静态存储:程序在运行开始就分配固定内存的存储方式。

就C 程序运行的内存来说,大致可分为3个部分:程序区,静态存储区(在运行开始就分配固定内存,直到程序运行结束才会释放内存),动态存储区(运行期间根据需要动态分配内存)。C 的变量,要么放在静态存储区,要么放在动态存储区。

静态存储区存放什么样的变量?

存放2类变量:全局变量和 static 修饰的局部变量。

不管是那种外部变量,外部全局变量或者内部全局变量(static 修饰的,只在当前源文件中有效的全局变量),都存放在静态存储区的。

动态存储区存放什么样的数据?

主要存放3类数据:函数的形参变量;非 static 的局部变量;函数执行的现场数据以及返回地址等。

可以在定义变量时指定变量的存储类别,C语言支持如下几种存储类别。

auto: 指定该变量采用自动存储机制——局部变量默认采用这种方式,对定义局部变量,auto 关键字可以忽略。

static:指定局部变量存到静态存储区。这样该变量所占空间会一直保存到程序退出。

register:指定该变量存放到寄存器内。

extern:用于声明外部变量。

静态局部变量和普通局部变量的区别

示例代码:

#import <Foundation/Foundation.h>

void fac(int n)
{
    auto int a = 1;
    // 定义静态局部变量,每次函数调用结束后,都会保存该变量的值
    static int b = 1;
    // a(每次调用时a总是等于1)的值加上n
    a += n;
    // b(b变量可以保留上一次调用的结果)的值加上n
    b += n;
    NSLog(@"a的值为:%d , b的值为%d" , a , b);
}
int main(int argc , char * argv[])
{
    @autoreleasepool{
        // 采用循环调用了fac()函数4次
        for(int i = 0 ; i < 4 ; i++)
        {
            fac(i);
        }
    }
}


每次调用 fac() 函数时,变量 a 的值总是1,而对于 static 修饰的变量而言,只有第一次调用该函数的时候才会等于初始值,以后该变量都会保存改动后的结果。

贴士:

实际上,程序员也可以不对 static 变量指定初始值,那么系统会在编译时自动为 static 变量分配默认的初始值。默认初始值都是广义的0.对整型 static 局部变量,该初始值总是0;对于浮点型的 static 局部变量,初始值总是0.0;对于指针型的 static 局部变量,初始值总是0x0(未指向任何有效对象的指针)

利用 static 变量的特性,轻松计算阶乘。代码如下:

#import <Foundation/Foundation.h>

int fac(int n)
{
    // static变量,第一次运行时该变量的值为1
    // f可以保留上一次调用函数的结果
    static int f = 1;
    f = f * n;
    return f;
}
int main(int argc , char * argv[])
{
    @autoreleasepool{
        // 采用循环,控制调用该函数7次
        for(int i = 1 ; i < 8 ; i++)
        {
            NSLog(@"%d的阶乘为:%d", i , fac(i));
        }
    }
}


特别指出:

虽然静态局部变量可以在函数调用结束后仍然在,但只能在本函数在此调用时访问该变量的值,其他函数不能访问该静态局部变量的值。

什么时候使用静态局部变量?

应该慎重使用静态局部变量,因为静态局部变量会一直占据固定的内存。考虑使用静态局部变量的情况如下:

需要变量能保留上次调用结束时的值。

希望变量只被初始化一次,以后只是被引用,而不希望对其重新赋值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: