变量的存储类别和生存期
变量在程序执行过程中占用存储单元的时间称为变量的生存期。分为:
动态变量
静态变量
内存中可供用户使用的存储空间分为三部分

动态存储区
动态变量存储在动态存储区。
当函数被调用时,系统会为函数中定义的变量分配一个动态存储单元,函数调用结束,这些存储单元就会被释放。
动态变量包括函数形参和函数内部定义的变量。
静态存储区
静态变量存储在静态存储区。
其在程序运行之初就被分配了存储空间,程序执行完毕才会释放存储空间。
静态变量包括:全局变量和使用关键字static定义的局部变量。
静态存储变量默认的初值为0。
定义变量关键字
在定义变量时,可以使用以下关键字定义其存储方式:
auto
static
register
extern
局部变量的存储
1. 自动存储类型变量
自动存储类型变量的存储单元被分配在内存的动态存储区中。自动存储类型变量的声明形式如下:
auto 类型 变量名;
自动存储类型是系统默认的类型,因此,在函数内部,下面两种定义方式等效:
int a ; float b; char c;
auto int a; auto float b; auto char c;
函数或复合语句内不作特别声明的变量、以及函数的形参,都是自动存储类型,它们在系统执行函数或复合语句时才被分配内存单元,在该函数或复合语句运行期间一直存在,在函数或复合语句运行结束时自动释放这些内存单元。
自动存储类型变量的作用域和生存期是一致的,在其生存期内都是有效的、可见的。
函数内部的自动存储类型变量在每次调用函数时,系统都会在内存的动态存储区为它们重新分配内存单元,在该函数被多次调用过程中,函数内的某个自动存储类型变量的存储位置不是固定的。
auto类型变量
关键字auto指定局部变量为动态存储方式
当省略关键字auto时,局部变量默认是动态存储方式。
2. 寄存器存储类型变量
寄存器存储类型变量的存储单元被分配在寄存器中,这种变量的声明形式如下:
register 类型 变量名;
例如下面定义的变量n:
register int n;
寄存器存储类型变量的作用域、生存期与自动存储类型变量相同。由于寄存器的存取速度比内存的存取速度快,因此通常将频繁使用的变量放在寄存器中(如循环体中涉及到的内部变量),以提高程序的执行速度。
由于计算机中寄存器的个数有限,寄存器的数据位数也是有限的,所以,定义寄存器存储类型变量的个数不能太多,并且只有整型变量和字符型变量可以定义为寄存器存储类型变量。
通常,寄存器存储类型变量的定义是不必要的,如今优化的编译系统能够识别频繁使用的变量,并能够在不需要编程声明的情况下,就把这些变量存放在寄存器中。
register变量
将频繁使用的变量定义为register变量,该变量存放在CPU的寄存器中,因为寄存器的存取速度远高于内存,从而可以显著提高程序的运行效率。

3.静态存储类型变量
静态存储类型变量所需的存储单元被分配在内存空间的静态存储区中。
静态存储类型变量的声明形式如下:
static 类型 变量名;
静态存储类型变量在编译时被分配内存、赋初值,并且只被赋初值一次。对未赋值的静态存储类型变量,系统自动给其赋值为0(字符型为'\0')。
在整个程序运行期间,静态存储类型变量占用静态存储区的固定的内存单元,即使它所在的函数调用结束,也不释放该存储单元,其值会继续保留。因此,下次再调用该函数时,静态存储类型变量仍然使用原来的存储单元,仍使用原来存储单元中的值。可以利用静态存储类型变量的这个特点,编写需要在被调用结束后仍保存局部变量值的函数。
静态存储类型的局部变量的作用域仍然是定义该变量的函数或复合语句内部。
虽然静态存储类型变量在整个程序运行期间都是存在的,但是在它的作用域外,它是不可见的,即不能被其它函数引用。
static声明静态局部变量
如果在定义局部变量时使用关键字static,则该变量为静态变量。
静态变量在程序执行期间会一直占用存储单元,它只能被初始化一次。
在每次调用其所在函数时,变量并不重新初始化,而是继续使用上次调用结束时保存的值。

全局变量的存储
1.全局变量的定义
全局变量存放在内存的静态存储区中。全局变量的生存期是整个程序的运行期。
全局变量分为程序级全局变量和文件级全局变量。程序级全局变量又称为全局存储类型的全局变量,文件级全局变量又称为静态存储类型的全局变量。
(1) 程序级全局变量
程序级全局变量在定义时不加任何存储类型的声明。程序级全局变量的作用域是整个程序。
一个C程序可以由多个文件组成,程序级全局变量是在程序的某个文件中定义的。
当程序级全局变量在程序的某个文件中定义后,程序的其它文件中若要使用它,只须用说明符extern声明,就可以在其它文件中使用。
(2) 文件级全局变量
定义时用说明符static进行声明的全局变量是文件级全局变量。
文件级全局变量的作用域是它所在的程序文件。虽然它在程序的运行期间一直存在,但它不能被程序中的其它文件所使用。用static声明的全局变量是为了限制它的作用域,达到信息隐蔽的目的。
在下面两种情况下,必须通过声明来扩展全局变量的作用域。
(1) 在同一个程序文件中,全局变量定义在后、使用在前。在使用前需要对其进行声明。如下所示:
#include <stdio.h>
int main()
{ int a, b, c;
extern int d; /*全局变量声明*/
d=b*b-4*a*c;
printf("%d", d);
return 0;
}
int d; /*全局变量定义*/
2) 程序由多个文件组成,多个文件要用到同一个全局变量,这时可以在某个文件中定义该变量,而在其它文件中用extern对该全局变量进行声明。
如下所示:
/*下面代码包含在文件file1.c中*/
# include <stdio.h>
int y=0; /*定义全局变量*/
int main()
{ f1( );
printf("%d\n ", y);
return 0;
}
/*下面代码包含在文件file2.c中*/
extern int y; /*声明全局变量*/
int f1( )
{int x;
scanf("%d", &x);
y=2*x;
}

