Menu Close

存储类: auto, extern, static, register

存储类定义 C 程序中变量/函数的范围(可见性)和生命周期。这些说明符放置在它们所修饰的类型之前。

存储类表示变量的可见性和位置。 它告诉我们可以从代码的哪一部分访问变量。 存储类用于描述以下内容:

  • 可变范围。
  • 变量将被存储的位置。
  • 变量的初始化值。
  • 变量的生命周期。
  • 谁可以访问变量?

因此,存储类用于表示所有有关变量的信息。

注意:变量不仅与数据类型,变量值相关联,而且也和存储类关联。

共有四种类型的标准存储类别。 下表代表“ C”中的存储类别。

There are total four types of standard storage classes. The table below represents the storage classes in ‘C’.

存储类 目的
auto 所有局部变量默认的存储类
extern 提供一个全局变量的引用,全局变量对所有的程序文件都是可见的
static 它是一个局部变量,即使将控制权转移到函数调用中,它也可以返回一个值。static 存储类指示编译器在程序的生命周期内保持局部变量的存在,而不需要在每次它进入和离开作用域时进行创建和销毁。
register register 存储类用于定义存储在寄存器中而不是 RAM 中的局部变量。这意味着变量的最大尺寸等于寄存器的大小(通常是一个词),且不能对它应用一元的 ‘&’ 运算符(因为它没有内存位置)

auto 存储类

使用auto存储类定义的变量称为局部变量。 auto代表自动存储类别。 如果未明确指定变量的存储类,则默认情况下该变量是auto存储类。

自动变量的范围仅受特定块限制。 一旦控制流退出该块,访问将被破坏。 这意味着只有声明了auto变量的块才能访问它。

关键字auto用于定义自动存储类。 如果你不赋予变量值,默认情况下,自动变量包含的值是垃圾值。

你可以看下面例子,每个块内的auto变量值是不一样的。离开了该块,变量自动失效。

#include <stdio.h>
int main( )
{
  auto int j = 1;
  {
    auto int j= 2;
    {
      auto int j = 3;
      printf ( " %d ", j);
    }
    printf ( "\t %d ",j);
  }
  printf( "%d\n", j);}


可以看出,随着控制流的不同, 变量j的值也是不一样的。auto是局部变量。

Extern 存储类

Extern代表外部存储类。 当我们具有在两个或更多文件之间共享全局函数或变量时,将使用外部存储类。全局变量对所有的程序文件都是可见的, 用于当有两个或多个文件共享相同的全局变量或函数的时候。

关键字extern用于声明另一个文件中的全局变量或函数,以引用已在原始文件中定义的变量或函数。

使用extern关键字定义的变量称为全局变量。 在整个程序中都可以访问这些变量。 请注意,extern变量无法初始化,它已经在原始文件中定义了

第一个文件: main.c

#include <stdio.h>
extern i;
main() {
   printf("value of the external integer is = %d\n", i);
   return 0;}

第二个文件: original.c

#include <stdio.h>
i=48;

你可以通过下列步骤运行以上程序。这个步骤可以告诉你大型C语言程序怎么运行的。

 

第一步)  Create new project,

  1. 选择 Console Application
  2. 点击 Go

第二步) 选择 C 并点击 Next

第三步) 点击 Next

第四步)进入文件夹和项目名,然后点击 Next

第五步) 点击 Finish

第六步) 双击main.c把 main 程序放在 main.c 文件,

第七步) 产生一个新文件 [File -> new -> Empty File , 另存为 original.c , 点击 对话框的”OK” ,把该文件加到现在 project (项目)。

第八步) 把上面 original.c 文件里面的程序放入 该 original.c  

第九步) save并运行。

可以看出,运行结果。main函数引用了ertern 全局变量i。

Static 存储类

静态变量在函数/文件中用作局部静态变量。 它们也可以用作全局变量。

  • 静态局部变量是一种局部变量,它在函数调用或块之间保留并存储其值,并且仅对定义该变量的函数或块可见。
  • 静态全局变量是仅对声明它的文件可见的全局变量。

static 存储类指示编译器在程序的生命周期内保持局部变量的存在,而不需要在每次它进入和离开作用域时进行创建和销毁。因此,使用 static 修饰局部变量可以在函数调用之间保持局部变量的值。

请记住,静态变量的默认初始值为零,并且在其生命周期内仅初始化一次。

#include <stdio.h> 

/* function declaration */
void next(void);
static int counter = 7; /* global variable */

main() 
{
   while(counter<10) 
   {
      next();
      counter++;   
   }
   return 0;
}

void next( void )   /* function definition */
{   
   static int iteration = 13; /* local static variable */
   iteration ++;
   printf("iteration=%d and counter= %d\n", iteration, counter);
}

全局变量可在整个文件中访问,而静态变量仅可用于声明该变量的特定部分。静态变量的寿命位于整个程序代码中。

register 存储类

register 存储类用于定义存储在寄存器中而不是 RAM 中的局部变量。这样运算速度会很快。因为CPU会很快找到该变量。

它类似于auto存储类, 该变量仅限于特定块。 唯一的区别是使用register存储类声明的变量存储在CPU寄存器中而不是内存中。 寄存器具有比主存储器更快的访问权限。

使用register存储类声明的变量没有默认值。 该变量通常在程序开始时声明。一个计算机系统中的寄存器数目有限,不能定义任意多个寄存器变量;局部静态变量不能定义为寄存器变量


#include <stdio.h>
main() 
   {
     {
       register int  weight;
       int *ptr=&weight ; /*it produces an error when the compilation occurs ,we cannot get a memory location when dealing with CPU register*/
      }
   }

下表总结了C编程中常用的每个存储类的主要功能

 

存储类 声明 存储位置 初始值 范围 生命周期
auto 在一个函数或块内 RAM 不可预期 在一个函数或块内 在一个函数或块内
register 在一个函数或块内 CPU 寄存器   乱码 在一个函数或块内 在一个函数或块内
extern 所有函数之外 RAM 零 整个项目文件内 程序运行
Static (local) 在一个函数或块内 RAM 零 在一个函数或块内 程序运行
Static (global) 所有函数之外 RAM 零 全局但指定一个文件内 程序运行

 

摘要

  • 存储类用于表示有关变量的其他信息。
  • 存储类表示变量的范围和寿命。
  • 它还告诉谁可以访问变量和从哪里访问变量
  • 自动,外部,寄存器,静态是“ C”中的四个存储类
  • auto用于块或函数中定义的局部变量
  • register于将变量存储在CPU寄存器中,而不是内存位置
  • 静态用于全局变量和局部变量。
  • Extern用于C项目文件之间的数据共享。
  • 一个项目可以包含很多文件