iOS开发技能树之C语言-存储方式、类别

存储方式

C语言根据变量的生存周期来区分,分为静态存储方式和动态存储方式。

  • 静态存储方式:在程序运行期间分配固定存储空间的方式。静态存储区存放了在整个程序执行过程中都存在的变量,如全局变量。

  • 动态存储方式:在程序运行期间根据需要进行动态的分配存储空间的方式。动态存储区中存放的变量是根据程序运行的需要而建立和释放的,通常包括:函数形式参数、自动变量、函数调用时的现场保护和返回地址等。

在内存中的用户存储空间分为:程序区、静态存储区、动态存储区。

存储类别

C语言中的存储类别分为四类:自动(auto)、静待(static)、寄存器(register)、外部的(extern)。

1、auto 自动变量 –局部变量

auto定义的变量为自动变量,auto可以省略,auto不写则隐含定为“自动存储类别”,属于动态存储方式。

函数的形参在函数中定义的局部变量(包含在符合语句中定义的局部变量),都是自动变量auto。存储在内存的动态存储区中。

int funny (int a) { /*定义函数,a为参数/形参*/
    auto int b ,c; /*定义b,c自动变量*/
    /*....*/
}

2、static 静态变量

static修饰的是静态变量,如果定义在函数内部,称之为静态局部变量;如果定义在函数外部,称之为静态外部变量。

静态变量都存储于静态存储区。

  • 静态局部变量

1、静态局部变量在编译时赋初值,第一次赋值有效,以后在调用时,直接使用上一次调用的值而不需要重新赋值。

2、静态局部变量属于静态存储类别,在静态存储区内分配存储单元,在程序整个运行期间都不释放。

扫描二维码关注公众号,回复: 183217 查看本文章

3、如果在定义局部变量时不赋初值的话,则静态变量在编译时自动赋初值0(对数值型变量)或空字符(对字符变量)。

void funny (int a) {
    static int index = 1;
    index += 1;
    printf("funny :%d\n",index);
}

int main(int argc, const char * argv[]) {

    for (int i = 0; i < 5; i ++) {
        funny(10);
    }
    printf("********\n");
    funny(0);

    return 0;
}

打印结果:
funny :2
funny :3
funny :4
funny :5
funny :6
********
funny :7
  • 静态外部变量/静态全局变量

全局变量都是放在静态存储区中的。一般来说,外部变量是在函数外定义的全局变量,它的作用域是从变量定义处开始,到本程序文件末尾。

静态外部变量,是为了使某些变量只限于被本文件引用,而不能被其他文件引用。

1、static int a,变量只可以在当前文件中使用,

2、int a,只是全局变量,可以在整个工程中使用,其他文件引用时需要extern关键字声明

test.c

static int staticInt_test = 100;

int pInt_test = 200;
/*-----------------------*/
main.c

int main(int argc, const char * argv[]) {

    extern int pInt_test;/*可以通过extern关键字声明,之后可以直接使用test.c中声明的变量 */
    printf("test:%d\n",pInt_test); /*打印结果:200*/

    extern int staticInt_test ;/*如果声明的是全局静态变量,这里在编译时会报错,找不到对应变量。*/
    printf("test static:%d\n",staticInt_test); /* 报错 */
    return 0;
}

static对局部变量和全局变量的作用不同,对局部变脸来说它使变量由动态存储方式改为静态存储方式。对全局变量来说,它使变量局部化(局部于本文件),但仍为静态存储方式。
从作用域角度看,凡有static声明的,其作用域都是局限的,或者都是局限于本函数内(静态局部变量),或者局限于本文件内(静态外部变量)。

3、register 寄存器变量

为提高效率,C语言允许将局部变量的值放在CPU的寄存器中,这种变量叫“寄存器变量”,关键字register声明。

void funny () {
    register int i,sum = 0;//定义为寄存器变量

}

只有局部自动变量和形式参数可以作为寄存器变量;一个计算机系统中的寄存器数据有限,不能定义任意多个寄存器变量,局部静态变量不能定义为寄存器变量

4、extern 外部变量

extern声明的变量是外部变量,表示把该变量的作用域扩展到此位置。外部变量的含义是某函数可以调用在该函数之后定义的变量。也可以调用其他文件中声明的外部变量。

  • 在一个文件内扩展外部变量的作用域
int main(int argc, const char * argv[]) {
    extern int count;
    printf("%d\n",count);

    return 0;
}

int count = 100;

打印结果:
100

/** 如果不作声明,将报错"Use of undeclared identifier 'count'" **/
  • 将外部变量的作用域扩展到其他文件,即在一个文件中引用另一个文件已经定义的外部变量
test.c

int pInt_test = 200;
/*-----------------------*/
main.c

int main(int argc, const char * argv[]) {

    extern int pInt_test;
    /*通过extern关键字声明,之后可以直接使用test.c中声明的变量 */
    printf("test:%d\n",pInt_test);
    /*打印结果:200*/

    return 0;
}
  • 作用

    1、在一个文件中扩展外部变量的作用域

    2、在一个文件中引用给另一个文件中已经定义的外部变量。

部分概念说明

数据存放的6中形式:

  • 1、程序代码区–存放程序编译后的可执行代码
  • 2、静态区(全局区)–全局变量和静态变量的存储是放在一起的,初始化的全局变量和初始化的静态变量在同一区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放
  • 3、常量区–常量存放位置,程序结束后由系统释放
  • 4、堆区–一般由程序分配和释放,如果程序不释放,程序结束时可能由操作系统回收(程序不正常结束则无法回收)
  • 5、栈区–由编译器自动分配并且释放,一般存放函数的参数、局部变量等
  • 6、寄存器区–有限容量的高速存储区,直接建立在中央处理器内部,用来暂存指令、数据和地址,一般用来保存栈顶指针、指令指针和现在正在被运行的指令。由于存储区其实是在中央处理器内部建立,不在内存中,因此不能将其划分到内存中。这里与内存的功能大致相同,都用来暂存数据。

—这部分说明来自博客

全局变量、局部变量

程序的编译单位是源程序文件,一个原文家可以包含一个或若干个函数。在函数内定义的变量是局部变量,在函数之外定义的变量称为外部变量,外部变量是全局变量(也称全程变量)。

全局变量可以为本文件中其他函数所共用,他的有效范围为从定义变量的位置到本源文件结束。

建议不再必要时不要使用全局变量:1、全局变量在程序执行的全部过程中都占用存储单元,而不是仅在需要时才开辟单元;2、使函数通用性降低;3、全局变量过多,降低程序的清晰性,难以清晰判断出每个瞬间各个外部变量的值。

作用域、生存期

一个变量的属性可以从两个方面分析,一个是作用域,一个事变量值存在时间的长短,即生存期。前者是从空间角度,后者是从时间角度。二者有联系,但不是同一回事。

如果一个变量在某个文件或函数范围内是有效的,就称该范围为该变量的作用域。在该作用域内可以引用该变量。

如果一个变量值在某一时刻是存在的,则认为这一时刻属于该变量的生存期,或称该变量在此时刻存在。

存储类别小结

1、从作用域角度分,有局部变量和全局变量
这里写图片描述

2、从变量存在的时间(生存期)区分,有动态存储和静态存储两种类型
这里写图片描述

3、从变量值存储位置区分
这里写图片描述

猜你喜欢

转载自blog.csdn.net/fengzhixinfei/article/details/80225720