zoukankan      html  css  js  c++  java
  • C语言_了解一下C语言中的四种存储类别

    C语言是一门通用计算机编程语言,应用广泛。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。

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

    1、auto(自动的)
    例:auto int a;定义的整形变量a的存储方式是自动存储的,也就是说动态的分配存储空间和释放存储空间。比如说,在一个调用函数里定义的变量,当我们调用这个函数时,CPU在动态存储区分配一个存储空间,这个存储空间用来放变量a的值,当调用函数执行完之后,CPU会释放这个存储空间(也可以这样理解,之前定义a时,CPU把一个存储空间给了a,a对这个存储空间有了使用权,其他的人无法去占用这个存储空间,当CPU释放这个存储空间时,也就意味着这个存储空间是无主的,其他的人可以占用它)。还有需要注意的是,当我们再次调用这个函数时,CPU分配的存储空间的地址并不一定是之前的地址,也就有了这样的一种情况,当我们定义一个变量时,不给它初始值,它的值是不确定的。
    我们之前编写程序的时候很少用到auto定义变量,其实我们之前定义的变量前面没有加static,编译系统会默认为是auto的存储方式,都会把变量存放在动态存储区。

    例如:

    int f(int a) /*定义 f 函数,a 为参数*/
    {auto int b,c=3; /*定义 b,c 自动变量*/
    ……
    }

    a 是形参,b,c 是自动变量,对 c 赋初值 3。执行完 f 函数后,自动释放 a,b,c 所占的存储单元。

    关键字 auto 可以省略,auto 不写则隐含定为“自动存储类别”,属于动态存储方式。

    2、static(静态的)
    例:static int a;定义的整形变量a的存储方式是静态存储的,静态局部变量是放在静态存储区内分配存储单元的,在整个程序运行期间都不释放,跟全局变量一样长期占用内存。但是静态变量和全局变量还是不一样的,比如说,静态变量只能在所定义的函数内引用,静态局部变量在函数调用结束后是仍然存在的,但不能被其他函数引用。
    静态局部变量是在编译时赋初值的,即只赋初值一次,在程序运行时它已经有了初值,以后每次调用函数时不再对其重新复制,而只是保留上次函数调用结束时的值。在定义静态局部变量时,如不赋初值,则编译时自动赋初值为0。
    有时在程序设计中定义一个全局变量,只限于被所在源文件引用,而不想让其他文件引用,则可在定义全局变量前面加static。
    3、register(寄存器的)
    对于一些频繁使用的变量,程序在执行的过程中,每次用到这些变量的时候,都要从内存取出来,运算完了之后还要写到内存中去,循环执行的次数越多,花费的时间就越多,为提高效率,C++允许将局部变量放在CPU的寄存器上,需要用到时直接从寄存器上取出参加运算,就不用再到内存中取;
    例:register int i,sum=0;

    for(i=0;i<10000;i++)
    sum+=i;

    i和sum都是频繁使用的变量,所以将他们定义为寄存器变量。

    当今的优化编译系统能够识别使用频繁的变量,从而自动将这些变量放在寄存器中,而不需要设定为register。因此,用register声明变量是不必要的。
    4、extern(外部的)
    要理解extern的作用,前提要对全局变量有所了解。
    全局变量的作用域只限于从定义那一行开始,到文件最后一行,终究只限于所在源文件中。如若想在其他源文件引用其他源文件的全局变量,则要在其他源文件声明该变量是extern的(来自外部的,其他源文件的),这样扩大了全局变量的作用域。
    例:char flag=1;

    extern char falg;

    赋初值是在定义时进行,外部变量声明不能赋初值,不能更改。

    以上内容摘自[百度百科]

    下面来个实际例子来测试下普通变量和静态变量

    fileOne.h头文件如下:

    #ifndef DMTestVariable_fileOne_h
    #define DMTestVariable_fileOne_h
     
    // 声明全局变量
    extern int globalVariable;
     
    void addOne();
    void testStaticGlobal();
     
    #endif

    fileOne.c文件如下

    #include <stdio.h>
    #include "fileOne.h"
     
    // 静态全局变量
    static int staticGlobalVariable = 12;
     
    void addOne()
    {
        // 全局变量加1
        globalVariable += 1;
    }
     
    void testStaticGlobal()
    {
        // 静态全局变量加1
        staticGlobalVariable += 1;
        printf("静态全局变量:%d
    ",staticGlobalVariable);
    }

    main.c文件如下:

    #include <stdio.h>
    #include "fileOne.h" // 定义性声明全局变量 int globalVariable = 10; void test() { // 静态局部变量 static int staticLocalVariable = 20; staticLocalVariable += 1; printf("静态局部变量值:%d ",staticLocalVariable); } int main(int argc, const char * argv[]) { int i; // 局部变量测试 int localVariable = 15; printf("局部变量%d ",localVariable); // 全局变量测试 addOne(); printf("全局变量:%d ",globalVariable); // 静态局部变量的测试 for (i = 0 ; i < 2; i++) { test(); } // 静态全局变量 for (i = 0 ; i < 2; i++) { testStaticGlobal(); } return 0; }

    结果如下:

    总结如下:
    全局变量,具有全局作用域,只需在一个源文件中定义,就可以作用于所有的源文件,当然其他不包含全局变量定义的源文件需要用extern关键字再次声明这个全局变量,如代码中的

    // 定义性声明全局变量
    int globalVariable = 10;

    全局变量,定义在main.c源文件中,在fileOne.c源文件中使用时有以下代码再次声明

    // 声明全局变量
    extern int globalVariable;

    静态全局变量,只能在其所在文件模块中的函数中使用,其他文件模块中的函数不能访问。如代码中的

    // 静态全局变量
    static int staticGlobalVariable = 12;

    只能在fileOne.c源文件中使用,不能在main.c源文件中使用。
    局部变量:只能在定义该变量的函数体内使用。如代码中的

    // 局部变量测试
    int localVariable = 15;

    只能在main函数中使用。

    静态局部变量:在函数内定义,但当函数退出后,静态局部变量始终存在,其占用的内存单元不会被释放,直到程序结束时才被释放。退出函数后尽管该静态局部变量还存在,但是不能使用它,如果再次调用定义该静态局部变量的函数,它又可以继续使用,而且保存了上次调用之后留下的值。如代码中的

    // 静态局部变量
    static int staticLocalVariable = 20;

    第一次调用test()函数输出的此静态局部变量值为21,第二次调用函数test()输出的此静态局部变量值为22。

  • 相关阅读:
    sklearn中决策树算法DesiciontTreeClassifier()调用以及sklearn自带的数据包sklearn.datasets.load_iris()的应用
    python 中feedParser
    Python中解码decode()与编码encode()与错误处理UnicodeDecodeError: 'gbk' codec can't decode byte 0xab
    Python中的排序方法sort(),sorted(),argsort()等
    Python 关于数组矩阵变换函数numpy.nonzero(),numpy.multiply()用法
    Python中where()函数的用法
    矩阵乘法np.dot()及np.multiply()以及*
    Python打开文件open()的注意事项
    给 Chrome浏览器 添加 Javascript小书签,查看当前页面全部加载的javascript文件及代码片段
    pycharm快捷键及中文说明【使用翻译工具一条一条翻译】
  • 原文地址:https://www.cnblogs.com/wt645631686/p/8178254.html
Copyright © 2011-2022 走看看