精华内容
下载资源
问答
  • 外部静态变量的作用域
    2021-11-08 14:18:14

    在C++中类的静态成员变量对于所有此类声明的变量来说共享。

    也就是说你声明了一个A类,A类里包含了一个静态的成员变量test,然后声明了多个A类的类变量,这些类变量共享一个成员变量test内存空间,有一个类变量改变了静态成员的值,其它类的成员变量test都会发生改变。

    其静态成员变量需要在外部进行初始化,因为它的内存区存储在Data全局区

    class A{
        public:
            static int test;    //这块会变成一块指向全局区内存的地址
    };
    //在外部进行初始化,分配内存代码也会在这里
    int A::test = 123;
    
    int main(){
    
        A t,y;
        t.test = 5;
        printf("%d,%d\n",t.test,y.test);
        return 0;
    }

    打印结果:

    5,5

    通过验证可以得到静态成员变量内存在生命周期里对于所有类变量来说共享

    并且你也可以直接使用它

    A::test = 8;

    这样也是有效的,可以把类内部静态成员变量理解为加了一个作用域的静态成员变量

    更多相关内容
  • 作用域的概念: ...这个可以访问的范围称为作用域...3、静态变量:用static修饰只存在于函数作用域的变量,函数执行结束后其值并不消失。注:初始化后不能再次进行初始化,不能用表达式来赋值。 复制代码 代码如下:functi
  • 局部变量:创建在栈区(向下生长),生命周期存在于当前作用域中。创建时若未初始化,则为随机值。全局变量:创建在static区,生命周期一直存在。创建时若未初始化,则为0。静态局部变量:切断了外部链接属性。创建在...

    局部变量:

    创建在栈区(向下生长),生命周期存在于当前作用域中。

    创建时若未初始化,则为随机值。

    全局变量:

    创建在static区,生命周期一直存在。

    创建时若未初始化,则为0。

    静态局部变量:

    切断了外部链接属性。创建在static区。

    创建时若未初始化,则为0。全局变量和静态变量的存储是放在一块的,初始化了的全局变量和静态变量在一块区域,

    未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。

    全局静态变量:

    切断了外部链接属性,创建在static区,生命周期一直存在。

    创建时若未初始化,则为0。#include

    #include

    int fun1()

    {

    static int n = 0;

    n++;

    return n;

    }

    int main()

    {

    int ret = 0;

    for (int i = 0; i 

    {

    ret = fun1();

    printf("%d\n", ret);

    }

    system("pause");

    return 0;

    }

    输出1,2,3……10.#include

    #include

    static int n;

    int fun1()

    {

    n = 0;

    n++;

    return n;

    }

    int main()

    {

    int ret = 0;

    for (int i = 0; i 

    {

    ret = fun1();

    printf("%d\n", ret);

    }

    system("pause");

    return 0;

    }

    输出10个1。

    extern:

    有外部链接属性,即可检测到外部文件。

    static:

    切断外部链接属性。

    位于static区的变量:

    整个生命周期均存在,如全局变量,静态变量。#include

    #include

    int b = 20;

    int main()

    {

    static int a = 10;

    int c = 5;

    printf("%p\n", &a);

    printf("%p\n", &b);

    printf("%p\n", &c);

    system("pause");

    return 0;

    }

    ad1f957cba0834da3f5640f13d693b24.png

    由此可知,静态变量和全局变量的存储地址很近,在同一区域,即:均存储在static区。

    展开全文
  • 看到这两个变量作用域,相信大家脑海里会浮现两个单词global&static。没错,就是这两个词。 我们知道,在所有函数外部定义的变量,拥有全局作用域。除了函数外,全局变量可以被脚本中的任何部分访问,要在一个函数中...
  • C++手稿:静态和全局变量作用域

    千次阅读 2018-05-07 08:44:06
    全局变量和静态变量的存储方式是一样的,只是作用域不同。如果它们未初始化或初始化为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

    展开全文
  • 存放在全局数据区的变量的生存周期存在于整个程序运行期间,而存放在栈中的数据则随着函数等的作用域结束导致出栈而销毁,除了静态变量之外的局部变量都存放于栈中。 作用域: 变量的可见代码域(块作用域,函数作用...

    首先要理解生存周期作用域的区别:

    生存周期: 变量从定义到销毁的时间范围。存放在全局数据区的变量的生存周期存在于整个程序运行期间,而存放在栈中的数据则随着函数等的作用域结束导致出栈而销毁,除了静态变量之外的局部变量都存放于栈中。

    作用域: 变量的可见代码域(块作用域,函数作用域,类作用域,程序全局作用域)。

     

    static变量是指静态的变量,不管是在全局还是局部声明的static变量都存放于程序的全局变量区域,所以它的生命周期是从程序开始到程序结束。但是static变量的作用域并不等同于它的生存周期,它的作用域决定于它被定义的位置。可以认为static变量的作用域<=生存周期。

     

    举一个局部声明的例子。在函数test中声明静态变量i:

    void test()

    {

    int m=3;

    static int i=5;

    }

    局部变量m存放在栈中,当test函数结束,m将被销毁;静态变量i不存放在栈中,而是存放于程序的全局变量区域,因此随着函数test的结束,它并不随着出栈操作而被销毁,它的生存周期存在于程序的整个运行期;然而m和i的作用域都仅存在于test函数中它们的定义之后,即test调用结束之后,m和i就不再可用,但是i仍存在于内存之中。

     

    再举一个全局声明的例子。在文件A 中定义静态变量j:

    int n=3; //默认为extern

    static int j=5; //声明为static

    全局变量和静态变量j都存放于程序的全局数据区域,它们的生存周期都是程序的整个运行期,但是n的作用域为全局作用域,可以通过extern在其他文件中使用,而j只能在文件A中使用,例如在文件B中:

    extern int n; //ok

    extern int j; //error: j在文件B中不可见

    int a=n;//ok:但这里有个初始化先后的问题,具体参见参考一

    int b=j;//error

    也就是说,在声明全局的static变量时,static没有改变它的生存周期,也即存储位置(因为全局变量本来就存储在全局数据域),而是将变量的作用域限制在当前文件中。

     

    中兴通讯2012校招笔试题的一道问答题:

     

    1. static全局变量与普通的全局变量有什么区别 ?

     全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。

      全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。

      这两者的区别在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。 

    static全局变量只初使化一次,防止在其他文件单元中被引用;   

    2.  static局部变量和普通局部变量有什么区别 ?

       把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。  

      static局部变量只被初始化一次,下一次依据上一次结果值;   

    3.  static函数与普通函数有什么区别?

       static函数与普通函数作用域不同,仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static修饰的函数),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件.

    static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝

     

     

    P.S. 

    C程序一直由下列部分组成:
      1)正文段(代码段)——CPU执行的机器指令部分;一个程序只有一个副本;只读,防止程序由于意外事故而修改自身指令;    
      2)初始化数据段(数据段)——在程序中所有赋了初值的全局变量,存放在这里。    
      3)非初始化数据段(bss段)——在程序中没有初始化的全局变量;内核将此段初始化为0。(这就是为什么全局内置类型变量会初始化,而局部变量就为未初始化的未知值)     
      4)栈——增长方向:自顶向下增长;自动变量以及每次函数调用时所需要保存的信息(返回地址;环境信息)。      
      5)堆——动态存储分。

    程序在内存中申请了代码段,全局数据段(初始化和未初始化),栈和堆:程序代码放于代码段,全局变量和静态变量存放在全局数据段中,一直存在直到程序结束,而局部变量都放于临时的栈中,随着作用域的结束随着出栈操作而销毁。malloc和new出来的内存不属于上面提到的程序申请的内存中,而是在系统中申请到的内存,所以如果在程序中没有明确free和delete的话,程序结束后该内存仍不会被释放,造成内存泄漏。例如:

    int test()

    {

    int * p=new int(3);

    }

    则test函数结束后,p指针本身被销毁,因为它是存在于函数栈中的局部变量,而p指向的int整型内容仍存在于内容堆中,没有被释放,造成内存泄漏。

    详细内存使用和参考http://blog.csdn.net/cc198877/article/details/8849694

     

    参考  

    http://www.cnblogs.com/jerry19880126/archive/2013/03/09/2951186.html

    http://www.cnblogs.com/jerry19880126/archive/2012/12/22/2829394.html
    http://www.cnblogs.com/stoneJin/archive/2011/09/21/2183313.html

    http://bbs.csdn.net/topics/350238100

    展开全文
  • PHP 中的每个变量都有一个针对它的作用域,它是指可以在其中访问变量(从而访问它的值)的一个领域。对于初学者来说,变量作用...这些函数具有它们自己的作用域,这意味着在一个函数内使用的变量不能在其外部使用,在
  • 静态变量 自动变量 寄存器变量[寄存器就是cpu内部可以存储数据的一些硬件东西] 3.简述全局变量和局部变量命名冲突的问题 1>在一个函数内部不能定义两个一样的局部变量 2>在一个函数内部如果定义的局部变
  • 1.块级作用域(私有作用域),经常在全局作用域中被用在函数外部,从而限制向全局作用域中添加过多的变量和函数。 (function(count){ for(var i=0;i<count>0、1、2、3、4 } console.log(i);//=>5 })(5); ...
  • 在PHP脚本中变量主要有:内置超级全局变量,一般的变量,常量,全局变量,静态变量等等,我们在使用它们的时候除了要正确地知道它们的语法以外,更重要的是,我们要知道它们在本质上的区别与联系—即它们的作用域的...
  • 主要介绍了Python 变量作用域的相关资料,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
  • 静态的意思不意味着它的值不变,而是该变量在内存中原地不动,即所属内存不会被系统清除 具有文件作用域的变量**自动具有...这是因为静态变量外部变量在程序被载入内存时已执行完毕 不能在函数的形参中使用st..
  • 静态变量

    千次阅读 2021-02-20 09:02:00
    静态变量作用域 是文件 ,只在这个文件中有效 静态局部变量 如果在某个块中,声明了某个静态变量,无论该块是否被访问,该静态变量都在内存中存在。 只有访问该块时,才能使用,Static内部变量 保存了上一次使用...
  • C语言里面静态变量有三种: 分别是外部链接性,内部链接性和无链接性.声明外部链接的变量的方法是在代码块外面声明它. 此变量是全局变量,多文件中亦可用.声明内部链接的变量的方法是在代码块外面声明它并加上static...
  • 静态变量的生存周期和作用域

    千次阅读 2016-11-26 21:04:58
    存放在全局数据区的变量的生存周期存在于整个程序运行期间,而存放在栈中的数据则随着函数等的作用域结束导致出栈而销毁,除了静态变量之外的局部变量都存放于栈中。作用域: 变量的可见代码域(块作用域,函数作用域...
  • 标识符的作用域 标识符的作用域是指某种标识符的作用范围。在C++中出现的各种标识符,具有不同的作用域作用域规则 总体规则:标识符只能在说明它或定义它的范围内是可见的,而在该范围之外是不可见的。 解释: ...
  • C语言变量作用域

    千次阅读 多人点赞 2020-03-03 16:32:10
    文章目录一、变量作用域二、全局变量三、局部变量四、函数的参数五、注意事项六、课后作业七、版权声明 一、变量作用域 作用域是程序中定义的变量存在(或生效)的区域,超过该区域变量就不能被访问。C 语言中有...
  • 在学习C++过程中,经常看到这么一个说法:“命名空间作用域下的....”,其实C++的作用域(以前一直都是认为只是参数的有效范围)一直都在用,但系统的划分可能却没划分过,因此,将C++的作用域划分记录在此。
  • 2.js中没有静态变量 3.闭包:函数内部可以调用函数外部的变量;反之,则不行 */ var r=10; function test1(){ var r2=”abc”; //alert(r) } //alert(r2);//不能访问的函数内部的r2 test1(); //嵌套的...
  • 一、静态变量: 在了解静态变量之前,读者需要知道什么是全局变量和局部变量。局部变量直至定义在函数内部的变量,在函数调用结束后,局部变量将消失。全局变量是指在函数体外定义的变量,它的生命期随着程序的结束...
  • 本文主要介绍了C++中的局部变量、全局变量、局部静态变量、全局静态变量的区别。具有很好的参考价值,下面跟着小编一起来看下吧
  • * PHP函数 -----变量的作用域 课程内容 局部变量 全局变量 静态变量 变量的作用域 变量需要先定义后使用,但这并不意味着变量定义后就可以随便使用,只有在它的作用范围中才可以被使用,这个作用范围称为变量的作用...
  • C/C++外部链接的静态变量

    千次阅读 2020-03-23 12:11:08
    外部链接的静态变量具有文件作用域外部链接和静态存储期。 该类别有时称为外部存储类别(external storage class),属于该类别的变量称为外 部变量(external variable)。把变量的定义性声明(defining ...
  • static 静态存贮分配变量(又分为内部静态和外部静态) extren 外部变量/全程变量(用于外部变量说明) register 寄存器变量 (用于在硬件寄存器中) 四大类所有变量必须先说明(定义),后使用。 自动(动态)...
  • 关于静态局部变量静态外部变量

    千次阅读 2017-11-09 19:14:10
    1:静态局部变量存储在静态存储区,如果赋有初值,函数调用期间只赋值一次,下次调用该函数时,静态局部变量值为上次调用之后的结果,原因:静态局部变量在函数调用期间是不释放的;而自动变量在每次调用函数时都会...
  • 外部变量是在函数的外部定义的全局变量,它的作用域是从变量的定义处开始一直到本程序的结尾。但有以下希望能扩展外部变量作用域的情况:
  • 静态变量的生存期和作用域

    千次阅读 2016-12-18 16:08:19
    静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量,例如外部变量虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成为静态外部变量,或称静态全局变量。...
  • Javascript变量作用域、变量提升

    千次阅读 2017-09-19 08:18:31
    Javascript变量变量提升以及作用域 执行环境对js编程的重要性不容忽视,理解其执行的原理,将有效提升编程素养。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 105,907
精华内容 42,362
关键字:

外部静态变量的作用域