zoukankan      html  css  js  c++  java
  • 静态局部变量、静态全局变量、extern全局变量、自动变量 札记

    1. 静态局部变量

      静态局部变量。

      从称呼上我们可以看出,静态局部变量首先是一个局部变量,因此其只在定义它的函数内有效,冠以静态的头衔后,其生存期就被延长了,不会随着函数的返回而被撤销。我们可以这样来理解:静态局部变量就是在程序生存期间一直有效,但只能在定义它的函数中使用的一种变量

      静态局部变量的声明比较简单,在声明局部变量的时候,加上关键字static就可以了。下面是一个用局部静态变量计算阶乘的具体例子。

    #include “stdio.h”
    
    int fac(int n)
    {
         static int nRet = 1;    //静态局部变量
    
        nRet *= n;
    
        return nRet;
    }
    
    void main()
    {
         for(int i=1;i<5;i++)
         {
             printf(“%d!=%d
    “,i,fac(i));
         }
         getchar();
    }
    

     在第一次调用函数fac的时候,函数fac中的静态局部变量nRet被初始化为1,如果没有默认指定初始化值得话,会被默认初始化为0. 主函数main中共进行了4次fac函数的调用:

      第一次调用:初始化nRet为1 函数返回时:nRet=1

      第二次调用时: nRet=1  函数返回时:nRet=2

      第三次调用时: nRet=2  函数返回时:nRet=6

      第四次调用时: nRet=6  函数返回时:nRet=24

      可以看出,静态局部变量在第一次调用的时候进行初始化,每次函数调用后,静态局部变量不会像局部变量那样被立即释放,而是继续有效,在下一次函数调用的时候会继续使用上一次的值。

    静态局部变量总结:

        (1)静态局部变量可以不初始化,有系统设置默认值为0;

        (2)静态局部变量默认只会在最开始定义静态局部变量时初始化,并且只有这唯一的一次初始化;

        (3)静态局部变量的作用范围仅仅只是块(如函数)内部。

      2.静态局部变量与其他变量类型的关系

      

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

      静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。

      局部变量也只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回。

      静态全局变量也具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里,不能作用到其它文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。

      从分配内存空间看: 全局变量,静态局部变量,静态全局变量都在静态存储区分配空间,而局部变量在栈里分配空间。

          使用的tips:

      Tips:
      A.若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
      B.若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
      C.设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题,因为他们都放在静态数据存储区,全局可见;
          D.如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用static变量(这样的函数被称为:带“内部存储器”功能的的函数)
          E.函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。

      3. static VS auto, static 全局变量 VS extern 全局变量

          和局部static相反的保留字是auto(一般可以不写,我们通常声明的变量,如 int a =19, 等,就是auto变量),static变量的生存期是永久(对于我们可见的代码来说),只初始化一次;而auto变量的生存期与所在块(复合语句)相同,每次进入块时进行初始化,
    如果是对象类型则在声明的地方执行构造语句。

      全局static变量是这样的:
      static int a;
      main()
      {
      ...
      }
      这时和它相反的是extern,这时static表明这个全局变量是“文件级”的,只能在这个文件中可见,但生存期和其它全局变量相同。

      

         4.从作用域的角度考虑

         extern全局变量、static全局变量和static局部变量的生存期都是“永久”(即:程序存在期间一直都可以使用),区别只是可见域不同。extern全局变量可见区域是工程,static全局变量可见区域是文件,而static局部变量的可见区域是块。
    从代码维护角度来看,对extern变量的修改可能会影响所有代码,对static全局变量的修改可能影响一个文件中的代码,而对static变量的修改可能影响一个块的代码;因此在选择变量类型时,优先级是static局部>static全局>extern全局。但它们有着共同的缺点:使用了这些类型变量的函数将是不可重入的,不是线程安全的。在C/C++标准库中有很多函数都使用了static局部变量,目前的实现中都为它们提供了两套代码,单线程版本使用static变量而多线程版本使用“线程全局变量”,比如rand,strtok等。

         5.自动变量示例

        自动变量:局部没有经过任何修饰的局部变量叫自动变量 (它存在于动态数据区——栈),这个区域内的数据随着程序的运行动态的生成和释放,函数返回就释放,函数要调用就生成。关键字:默认是atuo(一般不写).

     自动变量的特点:当程序执行到自动变量的作用域的时候就分配,不是到了声明代码才分配哦!到了代码分配就晚啦!当定义自动变量的函数执行结束后,程序将释放该自动变量的存储空间,留给其他自动变量使用。

    #include <stdio.h>
    
    void add(int n)
    {
        auto int s = 0;
        s = s + 1;
    
        printf("No.%d: s=%d
    ", n, s);
    }
    
    void main()
    {
        int i = 1;
    
        for(i; i<4; i++)
        {
            add(i);
        }
    }
    

     输出为:

    No.1: s=1
    
    No.2: s=1
    
    No.3: s=1
    

     从这个例子不难看出,自动变量的初始值在每次分配存储空间后都要重新赋值。

        

        

     

  • 相关阅读:
    [置顶] 文件批量重命名(工具)
    zookeeper源码分析之三客户端发送请求流程
    java set转list,数组与list的转换
    分布式电子邮件系统设计--转载
    redis 模糊删除实现
    eclipse 使用jetty调试时,加依赖工程的源码调试方法
    社交产品后端架构设计--转载
    solr服务器的查询过程
    What is corresponding Cron expression to fire in every X seconds, where X > 60? --转载
    zookeeper源码分析之二客户端启动
  • 原文地址:https://www.cnblogs.com/jiayouwyhit/p/3672768.html
Copyright © 2011-2022 走看看