C语言有丰富的数据类型和运算符,因此计算能力非常强大,计算过程中使用的值一般用变量来存储。变量也是有分类型的,不同类型的变量有不同的存储类型、不同的生命周期、不同的作用域,C语言也提供了一些关键字来设置变量的属性(比如设置存储类型、生命周期)。
1 变量的作用域
C语言根据变量作用域的不同,将变量分为局部变量和全局变量。
1.1 局部变量
(1) 定义:在函数内部定义的变量,称为局部变量。形式参数也属于局部变量。
(2) 作用域:局部变量只在定义它的函数内部有效,即局部变量只有在定义它的函数内部使用,其它函数不能使用它。
1.2 全局变量
(1) 定义:在所有函数外部定义的变量,称为全局变量。
(2) 作用域:全局变量的作用范围是从定义变量的位置开始到源程序结束,即全局变量可以被在其定义位置之后的其它函数所共享。
int gTest = 1;//全局变量,之后的函数都能访问这个变量
void test()
{
int a = 2;
printf("test()访问全局变量gTest = %d\n",gTest);
printf("test()访问局部变量a = %d\n",a);
}
int main()
{
test();
printf("main()访问全局变量gTest = %d\n",gTest);
//main函数无法访问 test()中的局部变量a
//printf("main()访问局部变量a = %d\n",a);
return 0;
}
2 变量的存储类型
(1) 变量的存储类型就是指变量存储在什么地方。有3个地方可以用于存储变量:普通内存、运行时堆栈、硬件寄存器。变量的存储类型决定了变量何时创建、何时销毁以及它的值能保持多久,也就是决定了变量的生命周期。
(2) 根据不同的存储类型,变量可以分为如下三种:自动变量、静态变量、寄存器变量。
2.1 自动变量
(1) 存储在堆栈中的变量称为自动变量,自动变量用关键字auto修饰。所有的局部变量在默认情况下都是自动变量,所以一般很少用这个关键字。
(2) 程序执行到代码块或者函数时,代码块或者函数内的自动变量才会被创建,代码块或者函数执行完毕,自动变量都会被销毁。如果一个代码块或者函数被重复执行,内部的自动变量也会重新创建和销毁
2.2 静态变量
(1) 存储在静态内存中的变量称为静态变量。所有的全局变量都是静态变量,被关键字static修饰的局部变量也是静态变量。
(2) 程序执行之前,静态变量就已经创建好了,直到程序结束。
2.3 寄存器变量
(1) 存储在硬件寄存器中的变量称为静态变量。寄存器变量比存储在内存中的变量访问效率更高(默认情况下,自动变量和静态变量都是放在内存中的。
(2) 被关键字register修饰的自动变量都是寄存器变量,并且只有自动变量才可以是寄存器变量,全局变量和静态局部变量不能是寄存器变量;寄存器变量只能是int,char和指针类型的。
(3) 程序执行到代码块或者函数时,代码块或者函数内的寄存器变量就会占用某个寄存器,一旦代码块或者函数结束,该寄存器就会被释放。
(4) 由于计算机中寄存器数目有限,不能使用太多的寄存器变量。如果寄存器使用饱和时,程序将寄存器变量自动转换为自动变量处理;为了提高运算速度,一般会将一些频繁使用的自动变量定义为寄存器变量,这样程序尽可能地为它分配寄存器存放,而不用内存。
int gTest = 1;//全局变量,也是静态变量
void test(int a,int b) //a,b都是自动变量
{
/*变量c是静态变量,所以该c会一直存在,知道程序结束 */
static int c = 0; //该语句在整个程序,只会执行一次
c++; //多次调用test(),打印的c值会不断变化
int d = 0; //自动变量, 多次调用test(),打印的d值不会变化
d++;
printf("test()访问全局静态变量gTest = %d\n",gTest);
printf("test()访问局部静态变量c = %d\n",c);
printf("test()访问局部变量d = %d\n",d);
}
int main()
{
int i;
//第二次,test()中的局部静态变量c变成2
for(i = 0;i < 2;i++)
{
test(0,0);
}
register int e = 5; //寄存器变量
printf("main()访问寄存器变量e = %d\n",e);
getchar();
return 0;
}
3 枚举
C语言中,除了int,char,指针这些基本类型,还有枚举(enum)这种基本数据类型。当一个变量只可能有几种固定的取值时,可以先定义一个包含这些取值的枚举类型,然后再定义枚举类型变量。
速度,一般会将一些频繁使用的自动变量定义为寄存器变量,这样程序尽可能地为它分配寄存器存放,而不用内存。
3.1 枚举的使用
(1) 定义枚举类型:enum 枚举名 {枚举元素1,枚举元素2,……}; 比如
enum Week {Sunday,Monday,Saturday,Wednesday,Thursday,Friday,Saturday};
(2) 定义枚举类型变量有三种方式:(1)先定义枚举类型,再定义枚举变量;(2)定义枚举类型的同时定义枚举变量;(3)省略枚举名称,直接定义枚举变量。
//第一种
enum Week {Sunday,Monday,Saturday,Wednesday,Thursday,Friday,Saturday};
eunm Week w;
//第二种
eunm Week {Sunday,Monday,Saturday,Wednesday,Thursday,Friday,Saturday} w;
//第三种
eunm {Sunday,Monday,Saturday,Wednesday,Thursday,Friday,Saturday} w;
3.2 使用注意
枚举元素(Sunday,Monday等)是作为整型常量处理,称为枚举常量。枚举元素的值取决于定义时各枚举元素排列的先后顺序。默认情况下,第一个枚举元素的值为0,第二个为1,依次顺序加1。也可以在定义枚举类型时改变枚举元素的值
//Sunday的值为0,Monday的值为1,依次类推
enum Week {Sunday,Monday,Saturday,Wednesday,Thursday,Friday,Saturday};
//Sunday的值为0,Monday的值为1,Saturday的值为5,Wednesday的值为6,依次类推
enum Week {Sunday,Monday,Saturday=5,Wednesday,Thursday,Friday,Saturday};
3.3 基本操作
枚举类型变量可以用枚举元素或者整型常量赋值,也可以遍历枚举元素
//Sunday的值为0,Monday的值为1,依次类推
enum Week {Sunday,Monday,Saturday,Wednesday,Thursday,Friday,Saturday} w;
w = Monday; //用枚举元素赋值,s的取值为1
w = 0; //用整型常量赋值,s为Sunday
//遍历
for(w = Sunday; s <= Saturday; s++)
{
printf("s的取值:%d\n",s);
}