zoukankan      html  css  js  c++  java
  • (C/C++学习笔记) 九. 变量的存储类型

    九. 变量的存储类型

    ● 变量的存储类型(见附页

    ● 注释

    ①对于自动变量,它属于动态存储方式。 但是也可以用static定义它为静态自动变量,或称静态局部变量,从而成为静态存储方式。由此看来,一个变量可由static进行再说明,并改变其原有的存储方式。

     

    ②"static"的含义不是指存储方式,而是指变量的作用域仅局限于本文件,一个函数内部的变量, 如果有关键字static修饰, 那么在函数调用结束时, 该静态变量的值不会消失。

    另外,函数前加static使得函数成为静态函数,指函数的作用域仅局限于本文件(所以又称内部函数)。使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数是否会与其它文件中定义的的函数同名。

    static函数与普通函数的区别是:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝。

     

    ③⑤ 在函数体内定义的静态变量为静态局部变量,在函数体外定义的静态变量为全局局部变量。

    The extern keyword is used in functions to declare a static external variable that is defined elsewhere.

     

    • 比较1. 普通的extern全局变量(external global variable)(编号4)和静态全局变量(static global variable)(编号5):
      二者在存储方式上没有不同,都分配在静态存储区,与程序共存亡。二者的区别在于extern全局变量的作用域是整个源程序,当源程序由多个源文件组成时,extern全局变量在各个文件中都是有效的,而静态全局变量则限制了其作用域,只在定义该变量的源文件内有效(一个文件),同一源程序的其他源文件中不能使用它。
    • 比较2. 静态局部变量(编号2和静态全局变量 (编号5):前者的作用域只是某一个包含它的函数体,后者的作用域是包含它的整个源文件。

     

    ● 全局变量和静态全局变量都属于静态存储类。生存期都是程序的一次执行,定义和初始化都是在程序编译时进行,其初始化只有一次。若没有初始化,则自动赋以(数值型)'' (字符型)

     

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

     

    ※变量的分类方法

    第一种:根据数据类型划分

     

    ●可以从时间和空间两个不同的角度来描述变量的特性:生存期,作用域

     

    第二种:根据变量的作用域——全局变量(在函数体外(包括主函数)定义的变量)、局部变量(在函数体内(包括主函数)定义的函数)

     

    第三种:根据变量的生命期(与变量的存储方式相关)——静态存储变量、动态存储变量

            ●变量的存储方式可分为:"静态存储"和"动态存储"两种。

            1. 静态存储变量(NP):在变量定义时就分配存储空间并一直保持不变,直至整个程序结束。典型的例子是全局变量。

            静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量(static variable),例如外部变量(extern variable)虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成为静态外部变量,或称静态全局变量。

            2. 动态存储变量: 在变量定义时不分配存储空间, 在程序执行过程中,使用它时才分配内存空间,使用完毕立即释放。典型的例子是局部            变量,函数的形式参数就是一种局部变量(还有其它任何在函数中定义的变量),在函数定义时并不为之分配存储单元,只是在函数被调用时,            才予以分配,函数调用完后立即释放。如果一个函数被反复调用,则反复地分配、释放形参变量的存储单元。

     

    第四种:根据作用域和生命期——auto变量、static变量、register变量、extern变量。

     

    第五种:同样根据作用域和生命期——全局变量、静态全局变量、静态局部变量、局部变量(没有动态全局变量和动态局部变量)

     

    ※ 按存储区域分:1. 全局变量、静态全局变量和静态局部变量都存放在内存的静态存储区域

                        2. 局部变量存放在内存的栈区(除了静态局部变量

        按作用域分:    1. 全局变量在整个工程文件内都有效

                        2. 静态全局变量只在定义它的文件内有效

                        3. 静态局部变量只在定义它的函数内有效,并且程序仅分配一次内存,函数返回后,该变量不会消失

                        4. 局部变量在定义它的函数内有效,但是函数返回后失效。

     

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

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

        3. 静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和全局变量的区别在于全局变量对        所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见(静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同,即只能在定义该变量的函数内使用该变量。退出该函数后,尽管该变量还继续存在,但不能使用它)

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

     

    //示例

    static int a,b;        //如果,此时在一个函数体内定义变量a,b, 那么它们是静态局部变量,如果在函数体外,那么它们是静态全局变量

    auto char c1,c2;    //c1,c2为自动字符变量

    static int a[5]={1,2,3,4,5};        //a为静态整型数组,,并未其初始化; 它有可能是局部的,也有可能是全局的

    register int a=1;                    //定义一个寄存器整型变量,并未其初始化

    //变量a不是保存在内存上,而是直接存储在CPU中的寄存器中

    extern int x,y;                        // x,y为外部整型变量

     

    ● 内存四区

    内存四区 Four areas of application memory (app memory)/RAM

    ※ 对于"全局区",有的资料将以区称为"数据区(data area)",包括静态区(全局区)和常量区

     

    ※ 有的资料还有内存五区的说法:

    BSS是英文Block Started by Symbol(以符号开始的块)的简称。BSS段属于静态内存分配。

     

    ※ 再看下面一个详细图:

    ●栈区: stack

        栈区是由编译器自动分配和释放,存放函数的参数值、局部变量的值等。

    ●堆区:heap

        堆区由程序员自行申请分配和释放,比如需要 malloc()函数来申请,free()函数来释放。

    ●数据区:data

        数据区主要包括:静态区/全局区,常量区,

            静态区(static)/全局区(global): 全局变量和静态变量是存储在一块的,即都在静态区(有的资料又称为"全局区")

            1. 初始化的全局变量和初始化的静态变量是在一块的。

            2. 未初始化的全局变量和未初始化的静态变量是在相邻一块。

     

            常量区:

                数据只读,常量字符串就放在这里。

    ●代码区:code

        代码区是存储编译后的可执行代码,机器码

     

    例如:

    int a=1; //a在栈区

    char s[]="123"; //s在栈区,"123"在栈区,其值可以被修改

    char *s="123"; //s在栈区,"123"在常量区,其值不能被修改

    int *p=new int; //p在栈区,申请的空间在堆区(p指向的区域)

    int *p=(int *)malloc(sizeof(int)); //p在栈区,p指向的空间在堆区

    static int b=0; //b在静态区

     

    ● 全局变量, 静态全局变量, extern变量举例

    全局变量, 静态全局变量, extern变量举例

    工程test源文件夹内有两个源文件: 1.cpp2.cpp

    //1.cpp

    #include <iostream.h>

     

    int a =1;    //定义一个全局变量

    static int b=2;        //定义一个静态全局变量,只能在本文件中使用

     

    //2.cpp

    #include <iostream.h>

    extern int a,b;

     

    int main()

    {

        a=3; //改变外部变量a的值

        cout<<"a="<<a<<endl;

        //b=4;

        //cout<<"b="<<b<<endl; 编译器会报错,因为b是另一个文件的静态全局变量

        return 0;

    }

     

    //也可以在主函数内引用外部变量

    //2.cpp

    #include <iostream.h>

     

    int main()

    {

        extern int a;

        a=3;

        cout<<"a="<<a<<endl;

        return 0;

    }

     

    ● 静态局部变量案例

    #include <iostream>

    using namespace std;

    int f(int a) //定义f函数,a为形参

    {

    auto int b=0; //定义b为自动变量

    static int c=3; //定义c为静态局部变量

    b=b+1;

    c=c+1;

    return a+b+c;

    }

    int main( )

    {

    int a=2,i;

    for(i=0;i<3;i++)

    cout<<f(a)<<" ";

    cout<<endl;

    return 0;

    }

     

  • 相关阅读:
    kali 所有版本
    kali有关问题及kali2018.2安装
    python2
    burpsuite 破解教程
    python生成个性二维码
    万能密码
    python 1
    python
    python 第三方库安装
    Androidstdio 简单界面设计 登陆系统
  • 原文地址:https://www.cnblogs.com/ArrozZhu/p/8377814.html
Copyright © 2011-2022 走看看