精华内容
下载资源
问答
  •  今天在论坛上看到有朋友发帖问道:既然静态全局变量全局变量都存储在全局数据区,为什么作用域却不一样呢?也许答案非常简单:C++就是这么规定的,静态全局变量全局变量的唯一区别就是作用域不同。  对一个...

    转载地址:http://blog.csdn.net/yunyun1886358/article/details/5632087 

     今天在论坛上看到有朋友发帖问道:既然静态全局变量与全局变量都存储在全局数据区,为什么作用域却不一样呢?也许答案非常简单:C++就是这么规定的,静态全局变量与全局变量的唯一区别就是作用域不同。

         对一个C++变量来说,有两个属性非常重要:作用域和生命周期,它们从两个不同的维度描述了一个变量--时间和空间。顾名思义,作用域就是一个变量可以被引用的范围,如:全局作用域、文件作用域、局部作用域;而生命周期就是这个变量可以被引用的时间段。不同生命周期的变量,在程序内存中的分布位置是不一样的。一个程序的内存分为代码区、全局数据区、堆区、栈区,不同的内存区域,对应不同的生命周期。

         有很多方法来指定一个变量的作用域和生命周期。最常见的,如:{ }、static修饰符等。下面按照作用域与生命周期来对变量做一个分类:

     

    全局变量

    • 作用域:全局作用域(全局变量只需在一个源文件中定义,就可以作用于所有的源文件。)
    • 生命周期:程序运行期一直存在
    • 引用方法:其他文件中要使用必须用extern 关键字声明要引用的全局变量。
    • 内存分布:全局数据区
    • 注意:如果在两个文件中都定义了相同名字的全局变量,连接出错:变量重定义
    • 例子:

    1. //defime.cpp  
    2. int g_iValue = 1;  
    3.   
    4. //main.cpp  
    5. extern int g_iValue;  
    6.   
    7. int main()  
    8. {  
    9.     cout << g_iValue;  
    10.     return 0;  
    11. }  

     

    全局静态变量

    •  作用域:文件作用域(只在被定义的文件中可见。)
    • 生命周期:程序运行期一直存在
    • 内存分布:全局数据区
    • 定义方法:static关键字,const 关键字
    • 注意:只要文件不互相包含,在两个不同的文件中是可以定义完全相同的两个静态变量的,它们是两个完全不同的变量
    • 例子:

    1. const int iValue_1;  
    2. static const int iValue_2;  
    3. static int iValue_3;  
    4.   
    5. int main()  
    6. {  
    7.     return 0;  
    8. }  

     

    局部静态变量

    • 作用域:局部作用域(只在局部作用域中可见)
    • 生命周期:程序运行期一直存在
    • 内存分布:全局数据区
    • 定义方法:局部作用域用中用static定义
    • 注意:只被初始化一次,多线程中需加锁保护
    • 例子:

    1. void function()  
    2. {  
    3.     static int iREFCounter = 0;  
    4. }  

     

    局部变量

    • 作用域:局部作用域(只在局部作用域中可见)
    • 生命周期:程序运行出局部作用域即被销毁
    • 内存分布:栈区
    • 注意:auto指示符标示

          还有一点要说明,掌握static关键字的使用很关键。以下是引用别人的一些经验之谈:

    Tips:

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

    来CSDN很久了,一直都想写点东西,今天终于出手了。水平有限,只能跟大家分享一些基础知识的总结,以共勉,共同提升。

     

    展开全文
  • 全局变量和静态变量的存储方式是一样的,只是作用域不同。如果它们未初始化或初始化为0则会存储在BSS段,如果初始化为非0值则会存储在DATA段,见进程的地址空间分配一文。静态变量作用域是当前源文件,全局变量的...

    全局变量和静态变量的存储方式是一样的,只是作用域不同。如果它们未初始化或初始化为0则会存储在BSS段,如果初始化为非0值则会存储在DATA段,见进程的地址空间分配一文。静态变量的作用域是当前源文件,全局变量的作用域是整个可执行程序。 值得注意的是:

    • 如果在头文件定义全局变量,在预编译期间#include的头文件会被拷贝进源文件中,编译器是不知道头文件的。
    • 虽然全局变量是全局作用域,但需要extern关键字来声明以通过编译。因为C++是强类型语言,编译时需要根据变量声明做类型检查。

    全局变量的引用

    C++源文件中引用外部定义的全局变量和引用外部函数是一样的语法,通过extern来声明:

    // file: a.cpp
    #include<iostream>
    extern int a;
    int main() {
        std::cout<<b<<std::endl;
        return 0;
    }
    
    // file: b.cpp
    #include<iostream>
    int a = 2;
    

    然后分别编译这两个文件,链接生成a.out并执行它:

    $ g++ a.cpp b.cpp
    $ ./a.out
    b.cpp
    2
    

    extern只是在当前文件中声明有这样一个外部变量而已,并不指定它来自哪个外部文件。所以即使extern变量名错误当前源文件也能通过编译,但链接会出错。

    头文件中定义

    因为头文件可能会被多次引用,在预编译时被引用的头文件会被直接拷贝到源文件中再进行编译。一个常见的错误便是把变量定义放在头文件中,例如下面的变量int a

    // file: a.cpp
    #include <iostream>
    #include "b.h"
    int main() {
        std::cout<<a<<std::endl;
        return 0;
    }
    
    // file: b.cpp
    #include<iostream>
    #include"b.h"
    void f(){}
    
    // file: b.h
    int a = 2;
    

    头文件b.h中定义了int a,它被a.cppb.cpp同时引入。我们将a.cppb.cpp分别编译是没有问题的,然后链接时会抛出错误:

    duplicate symbol _a in:
        /tmp/ccqpfU5e.o
        /tmp/ccCRi9nO.o
    ld: 1 duplicate symbol for architecture x86_64
    collect2: error: ld returned 1 exit status
    

    两个.o文件中的_a名称发生了冗余,这是变量重定义错误。

    头文件中声明

    因为声明操作是幂等的,而多次定义会引发重定义错误。所以 头文件中不应包含任何形式的定义,只应该包含声明,正确的办法是变量定义总是在源文件中进行,而声明放在头文件中:

    #include <iostream>
    #include "b.h"
    int main() {
        std::cout<<a<<std::endl;
        return 0;
    }
    
    // file: b.cpp
    #include<iostream>
    #include"b.h"
    int a = 2;
    
    // file: b.h
    extern a;
    

    然后编译链接执行都会通过,输出2

    $ g++ a.cpp b.cpp
    $ ./a.out
    2
    

    编译器看到g++ a.cpp b.cpp时会自动去查找b.h并进行预编译操作,因此不需要显式指定b.h

    静态全局变量

    非静态全局变量是外部可链接的(external linkage),目标文件中会为它生产一个名称供链接器使用;而静态全局变量是内部可链接的(internal linkage),目标文件中没有为链接器提供名称。因此无法链接到其他文件中,因此静态变量的作用域在当前源文件(目标文件)。虽然静态和非静态全局变量可能存储在同一内存块,但它们的作用域是不同的。 来看例子:

    // file: a.cpp
    #include <iostream>
    extern int a;
    int main() {
        std::cout<<a<<std::endl;
        return 0;
    }
    
    // file: b.cpp
    static int a = 2;
    

    然后g++ a.cpp b.cpp时发生链接错:

    Undefined symbols for architecture x86_64:
      "_a", referenced from:
          _main in ccPLYjyx.o
    ld: symbol(s) not found for architecture x86_64
    collect2: error: ld returned 1 exit status
    

    链接时未找到名称_a,因此静态变量在编译得到的目标文件中没有为链接器提供名称。所以其他目标文件无法访问该变量,静态全局变量的作用域是当前源文件(或目标文件)。

    全局变量初始化

    全局变量比较特殊,初始化有两种方式:

    • 静态初始化(static initialization):对于定义时给出初始化参数的全局变量,其初始化在程序加载时完成。根据是否被初始化、是否被初始化为0会把它存储在BSS或者DATA段中,参见进程的地址空间分配
    • 动态初始化(dynamic initialization):定义变量时可以不给出初始化参数,而是在某个函数中进行全局变量初始化。

    对于静态初始化,看这个例子:

    class C{
    public:
        C(){ std::cout<<"init "; }
    };
    C c;
    int main() { std::cout<<"main"; return 0; }
    

    main()进入之前,程序加载时动态初始化,程序输出为一行init main

    关于全局变量的初始化顺序,同一源文件中的全局变量初始化顺序按照定义顺序,不同源文件(编译单元)的全局变量初始化顺序并未规定。因此软件设计时不要依赖于其他编译单元的静态变量,可以通过单例模式来避免这一点。


    原文地址https://harttle.land/2015/09/30/cpp-static-and-global.html

    展开全文
  • 局部变量,全局变量,静态变量作用域,生命期? C++变量根据定义位置的不同,具有不同的作用域作用域可分为6种:全局作用域,局部作用域,语句作用域,类作用域,命名作用域和文件作用域。 从作用域看: 全局...

    局部变量,全局变量,静态变量的作用域,生命期?

    C++变量根据定义位置的不同,具有不同的作用域,作用域可分为6种:全局作用域,局部作用域,语句作用域,类作用域,命名作用域和文件作用域。

    从作用域看:

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

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

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

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

    从分配内存空间看:

             全局变量、静态局部变量、静态全局变量都在静态存储区分配空间,而局部变量在栈分配空间。全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上没有什么不同。区别在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其他源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其他源文件中引起错误。

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

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

    从以上分析可以看出,把局部变量改变为静态变量后是改变了他的存储方式,即改变了他的生存期。把全局变量改变为静态变量后是改变了他的作用域,限制了他的使用范围,因此static这个说明符在不同的地方起的作用是不同的。

    TIPS:

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

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

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

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

     

    展开全文
  • 全局变量、局部变量、全局静态变量、局部静态变量的区别。要从分配内存的位置和作用域入手来解释。 全局变量,分配的内存在静态存储区内存上面,其作用域是全局作用域,也就是整个程序的生命周期内都可以使用,...

    全局变量、局部变量、全局静态变量、局部静态变量的区别。要从分配内存的位置和作用域入手来解释。

    全局变量,分配的内存在静态存储区内存上面,其作用域是全局作用域,也就是整个程序的生命周期内都可以使用,同时,有些程序并不是由一个源文件构成的,可能有许多个源文件构成,全局变量只要在一个文件中定义,就可以在其他所有的文件中使用,当然,必须在其他文件使用extern关键字声明该变量。

    局部变量,分配内存是分配在栈存储区上的,其作用域也只是在局部函数内,在定义该变量的函数内,只要出了该函数,该局部变量就不再起作用,该变量的生命周期也只是和该函数同在。

    全局静态变量,分配的内存与全局变量一样,也是在静态存储内存上,其生命周期也是与整个程序同在的,从程序开始到结束一直起作用,但是与全局变量不同的是,全局静态变量作用域只在定义它的一个源文件内,其他源文件不能使用它。

    局部静态变量,分配的内存也是在静态存储内存上的,其第一次初始化后就一直存在直到程序结束,该变量的特点是其作用域只在定义它的函数内可见,出了该函数就不可见了。

    展开全文
  • 全局变量、全局静态变量、局部变量、局部静态变量区别
  • C++ 局部静态变量,全局变量,全局静态变量,局部变量的区别和联系C++变量根据定义位置的不同,具有不同的作用域作用域可分为6种:全局作用域,局部作用域,语句作用域,类作用域,命名作用域和文件作用域。从作用...
  • 静态变量的类型说明符是static,静态变量属于静态存储方式,但属于静态存储方式的不一定是静态变量,如外部变量(全局变量)就属于静态存储方式,但不是静态变量。必须有static加以定义才是静态变量,或静态全局变量...
  • 变量的作用范围 取决于变量的定义位置 1.局部变量(动态储存) 1、仅能在它所定义的语句块内有效 例如: 第一个x,为零的作用域为定义它的语句块作用域(红色格格),...全局变量静态储存) 从此程序开始到此程...
  • 作用域 全局变量 局部变量 静态变量 外部变量 常量 volatile变量  作用域作用域规则告诉我们一个变量的有效范围,它在哪儿创建,在哪儿销毁(也就是说超出了作用域)。变量的有效作用域从它的...
  • 1.之前我理解类是为了节省时间演化来的,因此里面的类的静态属性应该和模块中的全局变量作用范围类似,那类中的静态属性应该在整个类中都能访问。但实际为代码段所示。 2. ``` 2.1 全局变量能被内部定义函数所...
  • 作用域分:全局变量在整个工程文件内都有效;静态全局变量只在定义它的文件内有效;静态局部变量只在定义它的函数内有效,只是程序仅分配一次内存,函数返回后,该变量不会消失;局部变量在定义它的函数内有效,...
  • 1>全局变量全局作用域)。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。其他不包含全局变量定义的源文件需要用extern 关键字再次声明这个全局变量。 2>静态局部变量(局部作用域)。自从第一次被...
  • C#中变量分为:全局变量静态全局变量、局部变量静态局部变量。... 2、按作用域分  (1)全局变量在整个工程文件内都有效;  (2)静态全局变量只在定义它的文件内有效;  (3)静态局部变量...
  • x 全局静态变量 .data 当前文档(避免命名冲突) 程序运行周期 b 局部变量 栈 函数内部 函数运行周期 s1 局部变量 栈 函数内部 函数运行周期 p2 局部变量 栈 ...
  • 局部、局部静态、全局、全局静态变量联系区别: 首先明白6大作用域:全局作用域、局部作用域、文件作用域、命名空间作用域、语句作用域、类作用域 ...全局静态变量则作用与文件作用域,即当程序中有多个源
  • 不管是在全局还是局部声明的static变量都存放于程序的全局变量区域,全局变量也是存放于程序的全局变量区域,所以它们的生命周期是从程序开始到程序结束。 它们的作用域决定于它被存放和定义的位置。
  • 全局变量和全局静态变量的区别

    千次阅读 2015-06-30 22:24:49
    1)全局变量是不显式用static修饰的全局变量,全局变量...2)全局静态变量是显式用static修饰的全局变量,作用域是声明此变量所在的文件,其他的文件即使用extern声明也不能使用。// Book.h NSString *const bookName =
  • 比较全局变量、全局静态变量、局部变量、局部静态变量的区别,他们在编译完后存储位置在什么地方、初始化值在什么地方、内存什么时候分配、赋初值对这些变量有哪些影响等。要弄清楚这些问题,首先要弄清楚下面几个...
  • 说明全局变量、静态变量、局部变量、const变量的生命周期、作用域: 生命周期:是一个变量存在的周期。 作用域:是一个变量可以被引用的范围。最常见的如:{}、static修饰符等等。 1)全局变量: 作用域...
  • 全局变量,全局静态变量,局部变量,静态局部变量
  • 作用域 全局变量 局部变量 静态变量 外部变量 常量 volatile变量 作用域作用域规则告诉我们一个变量的有效范围,它在哪儿创建,在哪儿销毁(也就是说超出了作用域)。变量的有效作用域从它的定义点
  • 作用域 全局变量 局部变量 静态变量 外部变量 常量 volatile变量作用域:作用域规则告诉我们一个变量的有效范围,它在哪儿创建,在哪儿销毁(也就是说超出了作用域)。变量的有效作用域从它的定义点开始,到和定义...
  • 静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量,例如外部变量虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成为静态外部变量,或称静态全局变量。...
  • 标题:全局,局部,静态变量和变量的作用域,生存期; 内容:A.观看MOOC10.2,10.3; B(a).局部变量:定义在函数内部的变量(包括函数的形参),全局变量:定义在函数外面的变量 全局变量在所有函数中均可使用,...
  • 1、全局变量是不显示用static修饰的全局变量,但全局变量默认是静态的,作用域是整个工程,在一个文件内...2、全局静态变量是显示用static修饰的全局变量,作用域是所在的文件,其他的文件即使用extern声明也不能使用。
  • C/C++语言中的变量分为全局变量和局部...虽然常见的局部变量都是定义在函数体内的,也完全可以人为的增加一对大括号来限定变量作用域。如下所示:void f() { float x = 0; { int a; } }别小看这个作用域问题,这对

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 106,446
精华内容 42,578
关键字:

全局静态变量作用域