【C】存储类、链接和内存管理

作用域
  • 代码块作用域
  • 函数原型作用域
  • 文件作用域

链接

一个C变量具有下列链接之一:外部链接、内部链接或空链接。具有代码块作用域或者函数原型作用域的变量有空链接,意味着它们是由其定义所在的代码块或者函数原型所私有的。具有文件作用域的变量可能有内部或者外部链接。一个具有外部链接的变量可以在一个多文件程序的任何地方使用。一个具有内部链接的变量可以在一个文件的任何地方使用。关键字static表明变量具有内部链接,即该变量是当前文件所私有的,但是可以被文件中的任意函数使用。

存储时期

一个C变量有以下两种存储时期之一:静态存储时期和自动存储时期。如果一个变量具有静态存储时期,它在程序执行期间将一直存在。具有文件作用域的变量,不管是内部链接还是外部链接,都是静态存储时期;

具有代码块作用域的变量一般情况下就有自动存储时期。在程序进入定义这些变量的代码块时,将为这些变量分配内存;档推出这个代码块时,分配的内存将被释放。该思想把自动存储类的变量使用的内存视为一个可以重复使用的工作区或者暂存内存。

存储类

c使用作用域、链接和存储时期来定义5种存储类:自动、寄存器、具有代码块作用域的静态、具有外部链接的静态、以及具有内部链接的静态。5种存储类详细情况如下:

  • 自动:

    存储时期--自动 作用域--代码块 链接--空 声明方式--代码块内

    默认情况下,在代码块或函数的头部定义的任意变量都属于自动存储类,使用关键字suto可以使意图更加明显;

    除非显式的初始化自动变量,否则它不会被初始化,它的初始值是先前占用分配给它的空间的任意值。

  • 寄存器:

    存储时期--自动 作用域--代码块 链接--空 声明方式--代码块内,使用关键字register

    通常,变量存储在计算机内存中,如果幸运,寄存器变量可以被存储在CPU寄存器中,或更一般的,存储在速度更快的可用内存中,从而可以比普通变量更快的访问和操作,因为尹村器变量多是存放在一个寄存器而非计算机内存中,因此无法获得寄存器变量的地址。

    使用关键字register可以声明一个变量,但是声明仅仅是一个请求,编译器在请求和可用寄存器的个数和高速内存的数量之间做权衡,所以,一般情况下,它都是一个自动变量而不是寄存器变量,但是,仍然无法获得寄存器的地址。

  •     具有外部链接的静态:

    存储时期--静态 作用域--文件 链接--外部 声明方式--所有函数之外

    为了使得程序更加清晰,可以在使用外部变量的函数中使用关键字extern来再次声明它。如果变量是在别的文件中定义的,使用extern是必须的。在使用外部变量的函数中声明它不过是为了表明在这个函数中会使用这个变量,但是如果漏掉了extern关键字,就会创建一个自动变量,并且覆盖外部变量的定义。

    和自动变量一样,外部变量可以被显式的初始化,但是如果不初始化,它们会自动初始化为0,在外部声明的数组变量也是如此。但是,外部变量只能用常量来声明。

    外部变量第一次声明时为起留出了存储空间,它构成了变量的定义。第二次声明只是为了告诉编译器要使用先前定义的变量,因此不是一个定义。第一次声明成为定义声明,第二次声明成为引用声明。关键字extern表明该变量不是一个定义,因为它指示编译器参考其他地方。

    不要用extern来进行外部定义,只用它来引用一个已经存在的外部定义,一个外部变量只能进行一次初始化,而且一定是在变量被定义时进行。

  •   具有内部链接的静态:

    存储时期--静态 作用域--文件 链接--内部 声明方式--所有函数之外,使用关键字static

  •     空链接的静态:

    存储时期--静态 作用域--代码块 链接--空 声明方式--代码块内,使用关键字static

    可以创建具有代码块作用域,兼具静态存储的局部变量,这种变量和自动变量有相同的作用域,但是在函数调用之后,这种变量不会消失。从一次函数调用到下一次函数调用,计算机始终保持着它的值。在代码块内声明为static的静态变量,只在编译时初始化一次,如果不显式初始化静态变量,它们将被初始化为0;

你可能感兴趣的:(c)