精华内容
下载资源
问答
  • C++变量声明较随意,可以在使用的时候声明。 2.C程序中编译的时候将变量写入符号表,变量表,便于在函数方便的使用;C++是类安全处理,不能只在程序最开始的时候声明变量,在构造函数有可能不明确输入参数的定义...

    1.C程序中通常将变量声明在文件的最开始;C++中变量声明较随意,可以在使用的时候声明。

    2.C程序中编译的时候将变量写入符号表,变量表,便于在函数方便的使用;C++是类安全处理,不能只在程序最开始的时候声明变量,在构造函数有可能不明确输入参数的定义,这时候就要支持在需要的时候声明,而不是在函数的最开始。这个典例就是for循环中

     例:

    定义在for循环中,属于临时性的工作,对于一个for循环里面定义的变量,他的生命周期是for循环,C++中标准的定义,编译器会对此的处理是不同的:

    对于VC6.0,下面的连续代码是错误的。


    for(int i=0; i<10; i++) sum += i;

    for(int i=0; i<10; i++) sum += i;

    编译器会给出如下提示:error C2374: 'i' : redefinition; multiple initialization

    错误时变量i重复生命力额,原因很简单,VC在实现变量i的声明周期是遇到右大括号“}”才结束其定义的。所以上面的程序要改成:

    {
    for(int i=0; i<10; i++) sum += i;
    }
    for(int i=0; i<10; i++) sum += i;

    才能过编译器那一关。

    这一点也让很多程序员犯晕,在鼓励要用才声明的C++里面,竟然会存在for循环的重复定义。如果使用,

    for(int i=0; i<10; i++) sum += i;

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

    的话,这跟我们的逻辑又混乱了,在循环里面声明,却在循环外面使用。如果加上大括号又让程序显得特别奇怪。只能说,这是编译器的错,不是人的错,因为这两种选择都不是很合理。

    其实这跟早期编译器实现方式相关,笔者试了最新版本的G++编译器,上面的两段代码都没有问题。即for循环里面的变量的生存周期只在for里面有效。VC6.0的这种错误只能说它并不是一个标准的C++编译器。

    3.生命周期和作用域(作用域就是一个变量可以被引用的范围,如:全局作用域、文件作用域、局部作用域;而生命周期就是这个变量可以被引用的时间段)

    4.可执行程序在存储时(没有调入到内存)分为代码区(text)、数据区(data)和未初始化数据区(bss)3个部分

    5.

    (1)代码区(text segment)。存放CPU执行的机器指令(machine instructions)。通常,代码区是可共享的(即另外的执行程序可以调用它),因为对于频繁被执行的程序,只需要在内存中有一份代码即可。代码区通常是只读的,使其只读的原因是防止程序意外地修改了它的指令。另外,代码区还规划了局部变量的相关信息。
    (2)全局初始化数据区/静态数据区(initialized data segment/data segment)。该区包含了在程序中明确被初始化的全局变量、静态变量(包括全局静态变量和局部静态变量)和常量数据(如字符串常量)。例如,一个不在任何函数内的声明(全局数据):
    int maxcount = 99;
    使得变量maxcount根据其初始值被存储到初始化数据区中。
    static mincount=100;
    这声明了一个静态数据,如果是在任何函数体外声明,则表示其为一个全局静态变量,如果在函数体内(局部),则表示其为一个局部静态变量。另外,如果在函数名前加上static,则表示此函数只能在当前文件中被调用。
    (3)未初始化数据区。亦称BSS区(uninitialized data segment),存入的是全局未初始化变量。BSS这个叫法是根据一个早期的汇编运算符而来,这个汇编运算符标志着一个块的开始。BSS区的数据在程序开始执行之前被内核初始化为0或者空指针(NULL)。例如一个不在任何函数内的声明:
    long sum[1000];
    将变量sum存储到未初始化数据区。
    图3-1所示为可执行代码存储时结构和运行时结构的对照图。一个正在运行着的C编译程序占用的内存分为代码区、初始化数据区、未初始化数据区、堆区和栈区5个部分。

    (1)代码区(text segment)。代码区指令根据程序设计流程依次执行,对于顺序指令,则只会执行一次(每个进程),如果反复,则需要使用跳转指令,如果进行递归,则需要借助栈来实现。
    代码区的指令中包括操作码和要操作的对象(或对象地址引用)。如果是立即数(即具体的数值,如5),将直接包含在代码中;如果是局部数据,将在栈区分配空间,然后引用该数据地址;如果是BSS区和数据区,在代码中同样将引用该数据地址。
    (2)全局初始化数据区/静态数据区(Data Segment)。只初始化一次。
    (3)未初始化数据区(BSS)。在运行时改变其值。
    (4)栈区(stack)。由编译器自动分配释放,存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈。每当一个函数被调用,该函数返回地址和一些关于调用的信息,比如某些寄存器的内容,被存储到栈区。然后这个被调用的函数再为它的自动变量和临时变量在栈区上分配空间,这就是C实现函数递归调用的方法。每执行一次递归函数调用,一个新的栈框架就会被使用,这样这个新实例栈里的变量就不会和该函数的另一个实例栈里面的变量混淆。
    (5)堆区(heap)。用于动态内存分配。堆在内存中位于bss区和栈区之间。一般由程序员分配和释放,若程序员不释放,程序结束时有可能由OS回收。
    之所以分成这么多个区域,主要基于以下考虑:


    一个进程在运行过程中,代码是根据流程依次执行的,只需要访问一次,当然跳转和递归有可能使代码执行多次,而数据一般都需要访问多次,因此单独开辟空间以方便访问和节约空间。
    临时数据及需要再次使用的代码在运行时放入栈区中,生命周期短。
    全局数据和静态数据有可能在整个程序执行过程中都需要访问,因此单独存储管理。
    堆区由用户自由分配,以便管理。


    下面通过一段简单的代码来查看C程序执行时的内存分配情况。相关数据在运行时的位置如注释所述。
    //main.cpp
    int a = 0; //a在全局已初始化数据区
    char *p1; //p1在BSS区(未初始化全局变量)
    main()
    {
    int b; //b在栈区
    char s[] = "abc"; //s为数组变量,存储在栈区,
    //"abc"为字符串常量,存储在已初始化数据区
    char *p1,p2; //p1、p2在栈区
    char *p3 = "123456"; //123456\0在已初始化数据区,p3在栈区
    static int c =0; //C为全局(静态)数据,存在于已初始化数据区
    //另外,静态数据会自动初始化
    p1 = (char *)malloc(10);//分配得来的10个字节的区域在堆区
    p2 = (char *)malloc(20);//分配得来的20个字节的区域在堆区
    free(p1);
    free(p2);
    }

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

    //defime.cpp
    int g_iValue = 1;

    //main.cpp
    extern int g_iValue;

    int main()
    {
    cout << g_iValue;
    return 0;
    }



    全局静态变量

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

    const int iValue_1;
    static const int iValue_2;
    static int iValue_3;

    int main()
    {
    return 0;
    }



    静态局部变量

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

    void function()
    {
    static int iREFCounter = 0;
    }



    局部变量

    作用域:局部作用域(只在局部作用域中可见)
    生命周期:程序运行出局部作用域即被销毁
    内存分布:栈区
    注意:auto指示符标示
    还有一点要说明,掌握static关键字的使用很关键。以下是引用别人的一些经验之谈:

    Tips:

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

    展开全文
  • C/C++变量作用域

    2020-06-16 14:24:17
    C/C++变量作用域1. 局部变量2. 静态(static)局部变量3. 全局变量4. 静态(static)全局变量5. extern全局变量声明6. 全局函数和静态函数7. 总结 C语言变量作用域分为: 代码块作用域(代码块是{}之间的一段代码) ...


    C语言变量的作用域分为:

    • 代码块作用域(代码块是{}之间的一段代码)
    • 函数作用域
    • 文件作用域

    1. 局部变量

    局部变量也叫auto自动变量(auto可写可不写),一般情况下代码块{}内部定义的变量都是自动变量,它有如下特点:

    • 在一个函数内定义,只在函数范围内有效
    • 在复合语句中定义,只在复合语句中有效
    • 随着函数调用的结束或复合语句的结束局部变量的声明声明周期也结束
    • 如果没有赋初值,内容为随机
    #include <stdio.h> 
    void test(){
        //auto写不写是一样的
        //auto只能出现在{}内部
        auto int b = 10;
    }
     
    int main(void){
        //b = 100; //err, 在main作用域中没有b
     
        if (1){
            //在复合语句中定义,只在复合语句中有效
            int a = 10;
            printf("a = %d\n", a);
        }
        //a = 10; //err离开if()的复合语句,a已经不存在    
        return 0;
    }
    
    

    2. 静态(static)局部变量

    • static局部变量的作用域也是在定义的函数内有效
    • static局部变量的生命周期和程序运行周期一样,同时staitc局部变量的值只初始化一次,但可以赋值多次
    • static局部变量若未赋以初值,则由系统自动赋值:数值型变量自动赋初值0,字符型变量赋空字符
    #include <stdio.h> 
    void fun1(){
        int i = 0;
        i++;
        printf("i = %d\n", i);
    }
     
    void fun2(){
        //静态局部变量,没有赋值,系统赋值为0,而且只会初始化一次
        static int a;
        a++;
        printf("a = %d\n", a);
    } 
    int main(void){
        fun1();
        fun1();
        fun2();
        fun2();     
        return 0;
    }
    
    

    3. 全局变量

    • 在函数外定义,可被本文件及其它文件中的函数所共用,若其它文件中的函数调用此变量,须用extern声明

    • 全局变量的生命周期和程序运行周期一样

    • 不同文件的全局变量不可重名

    4. 静态(static)全局变量

    • 在函数外定义,作用范围被限制在所定义的文件中
    • 不同文件静态全局变量可以重名,但作用域不冲突
    • static全局变量的生命周期和程序运行周期一样,同时staitc全局变量的值只初始化一次

    5. extern全局变量声明

    extern int a;声明一个变量,这个全局变量在别的文件中已经定义了,这里只是声明,而不是定义。

    6. 全局函数和静态函数

      在C语言中函数默认都是全局的,使用关键字static可以将函数声明为静态,函数定义为static就意味着这个函数只能在定义这个函数的文件中使用,在其他文件中不能调用,即使在其他文件中声明这个函数都没用。对于不同文件中的staitc函数名字可以相同。
    注意

    • 允许在不同的函数中使用相同的变量名,它们代表不同的对象,分配不同的单元,互不干扰。
    • 同一源文件中,允许全局变量和局部变量同名,在局部变量的作用域内,全局变量不起作用。
    • 所有的函数默认都是全局的,意味着所有的函数都不能重名,但如果是staitc函数,那么作用域是文件级的,所以不同的文件static函数名是可以相同的。

    7. 总结

    在这里插入图片描述

    展开全文
  • c++变量作用域

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

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

    全局变量

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

    + expand sourceview plaincopy to clipboardprint?

    全局静态变量

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

    + expand sourceview plaincopy to clipboardprint?

     

    静态局部变量

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

    + expand sourceview plaincopy to clipboardprint?

     

    局部变量

    作用域:局部作用域(只在局部作用域中可见)
    生命周期:程序运行出局部作用域即被销毁
    内存分布:栈区
    注意:auto指示符标示
          还有一点要说明,掌握static关键字的使用很关键。以下是引用别人的一些经验之谈:

    Tips:

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

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

    首先要理解生存周期与作用域的区别: 
    生存周期: 变量从定义到销毁的时间范围。存放在全局数据区的变量的生存周期存在于整个程序运行期间,而存放在栈中的数据则随着函数等的作用域结束导致出栈而销毁,除了静态变量之外的局部变量都存放于栈中。 
    作用域: 变量的可见代码域(块作用域,函数作用域,类作用域,程序全局作用域)。

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

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

    #include<iostream>
    using namespace std;
    void test();//函数原型
    
    void test()
    {
    	static int m=5;
    	m+=1;
    	cout<<m<<endl;	//m作为静态变量,存在于整个程序运行周期中, 
    }
    int main()
    {
    
    	//int m=3; 
    	 static int i=5;
    	i=5;
    	test();
    	test();
    	test();
    	test();
    	test();
    	return 0;
    }
    

    运行结果



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

     

    展开全文
  •  今天在论坛上看到有朋友发帖问道:既然静态全局变量与全局...也许答案非常简单:C++就是这么规定的,静态全局变量与全局变量的唯一区别就是作用域不同。  对一个C++变量来说,有两个属性非常重要:作用域和生命
  • C++变量作用域

    2013-09-05 23:58:55
     按作用域分,全局变量在整个工程文件内都有效;静态全局变量只在定义它的文件内有效;静态局部变量只在定义它的函数内有效,只是程序仅分配一次内存,函数返回后,该变量不会消失;局部变量在定义它的函数内有
  • C++ 变量作用域

    2010-11-19 23:14:00
    静态屈居变量只能在本模块中使用,不可以在其他模块中用extern声明使用 静态局部变量有局部变量作用域,但是又有全局变量的性质。 下面是一个例子: main.cpp中的内容: #include ...
  • C/C++语言中的变量分为全局变量和局部...虽然常见的局部变量都是定义在函数体内的,也完全可以人为的增加一对大括号来限定变量作用域。如下所示:void f() { float x = 0; { int a; } }别小看这个作用域问题,这对
  • 一个asp.net页面有三个文件file.aspx、file.aspx.cs、file.aspx.designer.cs,是Page类,如果在该类中使用... 与Application的作用域相同,而且是可以跨页面使用的。最好在普通情况下尽量使用Session,Session就像C++
  • 也许答案非常简单:C++就是这么规定的,静态全局变量与全局变量的唯一区别就是作用域不同。  对一个C++变量来说,有两个属性非常重要:作用域和生命周期,它们从两个不同的维度描述了一个变量--时间和空间。...
  • 还真不对,结果是类的成员函数中的静态变量,他的作用域是这个成员函数,不管是不是这个类的同一个实例化对象,他们都共用这一个静态变量。也就是说函数的静态变量还是跟C 一样的解释。 直接给出测试代码吧。 // ...
  • C/C++全局变量和局部变量作用域问题

    千次阅读 2017-05-25 15:57:42
    局部变量(通常在函数中定义)的作用域是从声明的那一点开始,直到这个声明所在的块结束为止(一个块就是由{}围起来的一段代码)。全局变量(在所有函数、类、命名空间之外定义)的作用域从声明的那一点开始,直到这...
  • C++变量作用域和声明周期

    千次阅读 2016-08-10 10:35:06
    对一个C++变量来说,有两个属性非常重要:作用域和生命周期,它们从两个不同的维度描述了一个变量–时间和空间。顾名思义,作用域就是一个变量可以被引用的范围,如:全局作用域、文件作用域、局部作用域;而生命...
  • 全局变量和静态变量的存储方式是一样的,只是作用域不同。如果它们未初始化或初始化为0则会存储在BSS段,如果初始化为非0值则会存储在DATA段,见进程的地址空间分配一文。静态变量作用域是当前源文件,全局变量的...
  • C/C++静态变量

    2013-11-12 11:19:01
     (2)静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同,即只能在定义该变量的函数内使用该变量。退出该函数后, 尽管该变量还继续存在,但不能使用它。  (3)允许对构造类静态局部量赋...
  • 一、静态变量: 在了解静态变量之前,读者需要知道什么是全局变量和局部变量。局部变量直至定义在函数内部的变量,在函数调用结束后,局部变量将消失。全局变量是指在函数体外定义的变量,它的生命期随着程序的结束...
  • 从一段代码读懂C/C++变量作用域

    千次阅读 2016-09-06 08:48:57
    以下代码来自一道面试题,着重考察了C/C++中的变量作用域问题:#include <stdio.h>int count = 3; int main(void) { printf("%d\n", count); int i, sum, count = 2; printf("In main: count = %d\n", count); ...
  • c++变量作用域和生存周期

    千次阅读 2018-05-03 22:10:30
    四种变量作用域、生命周期、内存分布(全局、静态全局、静态局部、局部变量) 参考:《c++从入门到精通》人民邮电出版社C语言中变量作用域和生命周期https://blog.csdn.net/zsjalive/arti...
  • c/c++静态变量和静态函数

    千次阅读 2018-11-11 15:32:26
    而内存主要分为两类:静态存储区和动态存储区; 静态存储区分为:只读数据(READONLY DATA)区、以读写数据(RW DATA)区、未初始化区(BSS)。它们都是在程序编译连接阶段确定的,在程序执行的阶段不会改变。 ...
  • c++变量作用域

    2012-03-06 21:34:21
    全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量定义的源文件需要用extern 关键字再次声明这...静态局部变量具有局部作用域,它只被初始化一次,自从第
  • 作用域是表示某个标识符在什么范围内有效; 可见性是指标识符是否可见,可引用; 生存期,是指程序中的简单变量和类的对象,它们同自然界中的万物一样。也有自己的产生和消亡的生存期,变量和对象的生存期包含静态...
  • 静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量, 例如外部变量虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成为静态外部变量,或称静态全局变量。 ...
  • C++ 变量根据定义的位置的不同的生命周期,具有不同的作用域作用域可分为 6 种:全局作用域,局部作用域,语句作用域,类作用域,命名空间作用域和文件作用域。 从作用域看: 全局变量具有全局作用域。全局变量...
  • C++ 变量作用域 总结

    2010-09-22 19:49:00
    从网上的各种文章上摘录重新整理来的。 作用域可分为6种:  ...全局作用域, ...把 全局变量 改为 静态变量 是改变了它的作用域【文件作用域,只能在单个文件中访问】,限制了它的使用范围。  
  • 局部变量,全局变量,静态变量作用域,生命期? C++变量根据定义位置的不同,具有不同的作用域作用域可分为6种:全局作用域,局部作用域,语句作用域,类作用域,命名作用域和文件作用域。 从作用域看: 全局...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 72,692
精华内容 29,076
关键字:

c++静态变量作用域

c++ 订阅