zoukankan      html  css  js  c++  java
  • C Primer+Plus(十二)(1)

    第12章 存储类、链接和内存管理

    12.1存储类

    存储类,也可称为存储模型,即一个变量,它在内存中是如何存放,生存多久,以及作用范围。先说明几个名词的含义:

    12.1.1作用域

    作用域描述的是一个变量(标识符)可以在程序哪些区域被使用,包括:代码块作用域、函数原型作用域、文件作用域。

    int x;                 //此处x作用域为整个程序文件
    main(void)
    {
      int functiona(int b);    //此处为函数声明,b只是参数表示,不是特指变量
      int a;                   //a作用域从此处至main函数结束
      for(int i=0;i<a;i++)     //i作用域仅为for循环代码段
       {int m;                 //m作用域从此处至for循环结束   
        functiona(m);
    functionb(m); ...; } }
    int functiona(int x) //此处x作用域为函数原型,不同于程序开始处的x,程序开始处的x变量此时已被屏蔽 {int a; //a作用域从此处至functiona函数结束,不同于main中a,main中a此时已被屏蔽 ... } //被调函数结束,被屏蔽的x和a解封
      int functionb(int a1){} 

    说明,对于上例程序中开头的变量x,在程序functiona和functionb中均是可用的,只是因为functiona中定义了一个同名变量,导致其在functiona中被屏蔽。

    12.1.1链接

    链接是指什么?粗略看完整章,用自己的理解说明一下:一个变量,除去在程序文件中的作用域之外,还可以在哪里使用?若可以被其他程序文件使用,则称外链接;若可以在本文件内部任何地方使用,则称内链接。而仅具有代码块作用域或函数原型作用域的变量不具备链接性,称为空链接。

    int a=5; //具备文件作用域,具备外链接性,称为外链接
    static int b=6;   //具备文件作用域,内链接
    int main(void)
    {...
    }

    12.1.3存储时期

    C变量有两种存储时期:静态存储时期(static storage duration)和自动存储时期(automatic storage duration)。

    静态存储时期表示该类变量在程序执行期间将一直存在。具有文件作用域的变量具有静态存储时期特性。

    自动存储时期表示该类变量仅在程序运行在其作用域内时存在,一旦程序退出作用域,存储该变量的内存将被释放。代码块作用域和函数原型作用域的变量一般均为自动存储类型。

    在上述三个概念介绍后,提出5种存储类型:


     
             
             
             
             
             
             
             
             
             
             
             
             

    存储类                        时期                    作用域                     链接                             声明方式

    自动         自动       代码块        空         代码块内

    寄存器        自动         代码块        空         码块内,使用关键字register

    具有外部链接的静态      静态       文件         外部        所有函数之外

    具有内部链接的静态  静态         文件         内部        所有函数之外,使用关键字static

    空链接的静态     静态       代码块        空         代码块内,使用关键字static


    依次介绍:

    12.1.4自动存储类型的变量

    具有:自动存储时期,代码块作用域,空链接特性。一般情况,在代码块头部或函数头部定义的变量都属于自动存储类型。

    int main()
    {int a;   //a属于自动存储类
      auto int b;  //也可用auto关键字显式声明自动存储类变量b
      int f1();
      ...
    }
    int f1(void)
    {
       int m;   //正常声明一个自动存储类变量
       auto int n;  //也可通过auto
      ...
    }

    自动存储时期意味着程序进入该变量所处代码块时候,变量被分配内存空间,当程序结束该代码块时候,自动变量就不存在了,即所占内存被释放。

    *对于自动存储类变量,若未被初始赋值,则其值是其所占内存单元里的数值,也就是不可预知的。

    12.1.5寄存器存储类变量

    当希望变量可被更快速的访问和操作,因为VPU访问寄存器单元肯定比访问内存更快速,则可选用该类型。

    声明形式:register int a;通过该声明使得在程序编译到此句时,给变量a分配寄存器(若寄存器不够用,则分配相对更快速的内存单元)。因多数情况下该声明后分配存储区为寄存器,而寄存器的地址是不可读的,则该类变量无法进行&操作,因为取不到地址。

    12.1.6具有代码块作用域的静态变量

    静态变量是指变量的存储位置固定不动。回想一下,在程序文件头声明定义的变量都是静态变量;另一种静态变量则是具有代码块作用域的静态变量,它的作用域仅限于代码块,同时具备空链接性,但它的生命周期是贯穿从定义初始,到程序结束的。

    #include<stido.h>
    int main(void)
    {
       int i;
       void fs();
       for(i=0;i<2;i++)
         fs();
       return 0;
    }
    void fs()
    {int x=1;
      static y=2;
      printf("%d-%d",x++,y++);
    }

    上程序在TC3.0下运行结果如下:

    1-2

    1-3

    函数fs体内定义了两个变量,x是明显的自动存储类变量,作用域和生命周期都仅限于每一次调用中的fs,每一次调用fs都会临时给每次的x分配内存空间,并初始化数值1;而y是静态存储类,因其在函数体内定义,其作用域也仅限于函数体,但其在整个程序运行期间(从y被定义至程序结束)都在固定地址存放,并且只有当函数fs被调用时候才可以被使用。

    代码块作用域静态存储类变量不能用于函数的参数。

    12.1.7具有外部链接的静态变量

    该类变量具有文件作用域、静态存储类、外部链接特性。也称为“外部变量”。在程序中所有函数之外定义声明一个变量,则创建了外部变量。

    (1)定义声明:是指外部变量的初始创建。

    (2)内部引用声明:指在同一文件中,函数在使用该外部变量时候通过关键字extern的引用声明,该声明一般可省略。

    (3)外部引用声明:在其他文件中若要使用另一文件内创建的外部变量,则必须显式声明。

    ------file a---------
    int tsa;          //定义声明外部变量tsa
    int tsb=1;     //也可定义声明外部变量tsb,并初始化
    int main()
    { int i,j;
       ...
    }
    void f1()
    {
       extern int tsa;   //因在同一文件里,该处声明也可以省略
       ....
    }
    ----------------------------
    ---------file b---------
    #include"a.h"        //包含引用声明变量的定义文件
    extern int tsb;   //引用声明,必须的,因为该变量的定义不在同一文件中
    int main()
    {...
    }

    再看下例:

    #include <stdio.h>
    int x1;   //定义声明外部变量x1
    int main()
    { int x1;   //定义声明自动变量x1,和上述外部变量只是同名
       ....       //在main代码块里,只有自动变量x1起作用
    }

    *若外部变量定义声明时候未初始赋值,则其初始值为0。并且外部变量只可以用常量表达式来初始化赋值。

    例如对于外部变量a:  int a=2*b;   //是非法的,即便变量b事先已被定义

    *定义和声明:区别在于系统何时给变量分配存储空间则称为定义。对于引用声明关键词extern的使用,若和外部变量定义语句在同一文件中则可省略;若不在同一文件则该关键字是不可省略的。对于应用声明,还需要注意如下:

    int a1=2;  //定义声明一个外部变量a1,并赋值2
    int main()
    {
       extern int a1;   //正确,但可省略
       extern int a1=3;  //错误,该语句仅是引用声明,而不能赋值;即便理解为定义声明一个外部变量也应该是在所有函数之外进行
       //若忽略上两句
       a1=3;    //正确
    ...
    }

    12.1.8具有内部链接的静态变量

    该类变量具有:静态存储时期,文件作用域以及内链接特性。在所有函数外部通过关键字static定义声明该类变量。

    (1)定义声明:是指外部变量的初始创建。

    (2)内部引用声明:指在同一文件中,函数在使用该外部变量时候通过关键字extern进行声明,该声明一般可省略。但该声明不改变内部链接特性。

  • 相关阅读:
    linux命令行总结给自己看的版本
    搜集关于人脸识别的评价指标时的感慨
    配置面部数据增加的代码环境流程记录
    关于Linux前后台进程切换
    【转&改进】Linux MPI 单机配置
    How did I Install DCGAN
    kali的安装
    TensorFlow的安装
    strcmp用法
    分享一个MVC的多层架构,欢迎大家拍砖斧正
  • 原文地址:https://www.cnblogs.com/tsembrace/p/3146372.html
Copyright © 2011-2022 走看看