• 全局变量/静态全局变量/局部变量/静态局部变量的异同点


    一、程序的内存分配介绍
      一个由C/C++编译的程序占用的内存分为以下几个部分
    1、栈区(stack): 由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
    2、堆区(heap): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
    3、全局区(静态区)(static):全局变量和静态变量的存储都是放在静态区的,初始化的全局变量和静态变量在一块区域(.data),未初始化的全局变量和未初始化的静态变量在相邻的另一块区域(.bss)。  程序结束后由系统释放。
    4、文字常量区:常量字符串就是放在这里的(.rodata)。 程序结束后由系统释放。
    5、程序代码区:存放函数体的二进制代码(.text)。
    二、程序例子
    //main.cpp
    int a = 0;           // 全局初始化区
    char *p1;           // 全局未初始化区
    main()
    {
      int b;                  // 栈区
      char s[] = "abc";  // 栈区
      char *p2;            // 栈区
      char *p3 = "123456";     // "123456/0" 在常量区,p3在栈区
      static int c =0;               // 全局(静态)初始化区
     
      p1 = (char *)malloc(10);
      p2 = (char *)malloc(20); // 分配得来的10和20字节的区域就在堆区
     
      strcpy(p1, "123456");    // "123456/0" 放在常量区,编译器可能会将它
                                         // 与p3所指向的"123456"优化成一个地方。
    三、 问题:static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别? 

    从作用域看:

    • 全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包括全局变量定义的源文件需要用extern关键字再次声明这个全局变量。      
    •  静态全局变量也具有全局作用域,他与全局变量的区别在于如果程序包含多个文件的话,他作用于定义它的文件里,不能作用到其他文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同的静态全局变量,他们也是不同的变量。
    • 局部变量具有局部作用域,他是自动对象,他在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用结束后,变量就被撤销,其所占用的内存也被收回。         
    • 静态局部变量也只具有局部作用域。它只被初始化一次,自从第一次初始化直到程序与你新内阁结束都一直存在,他和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。

    从分配内存空间看:

    • 全局变量、静态局部变量、静态全局变量都在静态存储区分配空间,而局部变量在栈分配空间。
      
     
      1) 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
      2) 从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围,因此static这个说明符在不同的地方起的作用是不同的。                   
      3) static函数与普通函数作用域不同,仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件   
      综上所述:
    static全局变量与普通的全局变量有什么区别:
    static全局变量只初使化一次,防止在其他文件单元中被引用;   
    static局部变量和普通局部变量有什么区别:
    static局部变量只被初始化一次,下一次依据上一次结果值;   
    static函数与普通函数有什么区别:
    static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝

    TIPS:

    1、若全局变量仅在单个文件中访问,则可以讲这个变量修改为静态全局变量。

    2、若全局变量仅在单个函数中使用,则可以将这个变量修改为该函数的静态局部变量。

    3、全局变量、静态局部变量、静态全局变量都存放在静态数据存储区。

    4、静态变量会被放在程序的静态数据存储区里,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是他与堆栈变量和堆变量的区别

    5、变量用static告知编译器,自己仅仅在变量的作用域范围内可见。这一点是他与全局变量的区别。

    6、函数中必须要使用static变量的情况:当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。

    7、全局变量作用域是跨越多个源程序的,因此全局变量不能重名。静态变量作用域是位于单个源程序内,多个源程序可以有同名的全局静态变量。静态局部变量可以和静态全局变量重名,前者会将后者屏蔽掉。

  • 相关阅读:
    UML描述
    Tomcat优化
    Tomcat源码
    Tomcat架构
    搭建K8s集群[无需科学shangwang]
    minikube安装
    K8S核心组件和架构图
    Docker数据持久化
    Java 内存溢出(java.lang.OutOfMemoryError)的常见情况和处理方式
    cookie与session区别?
  • 原文地址:https://www.cnblogs.com/zhangwuji/p/5297631.html
Copyright © 2020-2023  润新知