变量的作用域
根据变量定义的位置不同,每个变量都只能在一定范围内访问,称之为变量的作用域。按照作用域可将变量分为局部变量和全局变量。
1、局部变量
在一个函数内部定义的变量称为局部变量。局部变量的作用域仅限于定义它的函数之内,任意函数不能访问其他函数定义的局部变量。特别的,在不同函数内可以定义同名的局部变量,但代表不同的变量,不会发生命名冲突。
int a1(int x)
{
int a; //变量x、a在a1内有效
}
int a2()
{
int b,c; //变量b、c在a2内有效
}
void main()
{
int a,b,c; //变量a、b、c在main内有效,与a1和a2中的a、b、c代表不同变量
}
说明:
- 形参也是局部变量,例如a1中的x。
- 编译时,系统不为局部变量分配内存,而是当局部变量所在函数被调用时才临时分配内存,调用完,释放内存。
2、全局变量
在所有函数之外定义的变量称为全局变量。其作用域是从定义的位置开始到本源文件结束。
说明:
- 在上例中m、n、x、y都是全局变量。但m、n的作用域为a1和main,而x、y的作用域为main。
- 如果在同一个源文件中全局变量和局部变量同名,则在局部变量的作用范围内,全局变量不起作用。
int a=1; //定义全局变量a赋值1
void main()
{
int a=2; //定义局部变量a赋值2
printf("%d\n",a); //使用main函数定义的变量a的值,打印出2
}
- 全局变量在函数编译阶段分配内存,故只进行一次初始化。如果定义没有赋初值,系统会自动给其赋值,数值型赋0,字符型赋空字符。
变量的储存类型
1、自动变量
函数中的局部变量如果不用关键字static声明,它就是自动变量,自动变量存放在动态储存区中。此外,还可以用auto作自动类型说明。
auto int a; //等价于 int a;
说明:
- 全局变量不能是自动变量。
- 每调用一次函数时都重新给它赋值,两次调用之间不会保持它的值。
void f(int n)
{
int a=0;
a++;
printf("第%d次调用 a=%d\n",n,a);
}
void main()
{
f(1);
f(2);
f(3);
}
上例运行结果
第1次调用 a=1
第2次调用 a=1
第3次调用 a=1
2、静态变量
静态变量储存在内存中的静态储存区,编译系统为其分配固定的分配空间,重复使用会保留变量中的值。
定义静态变量的一般形式如下
static int a;
(1)静态全局变量
在定义全局变量时,若用关键字static限定,称之为静态全局变量。静态全局变量只能在定义它的源程序文件中使用。而非静态全局变量可以扩展到整个源程序。
(2)静态局部变量
在定义局部变量时,若用关键字static限定,称之为静态局部变量。静态局部变量在函数调用结束后仍保持原值,所占用的储存单元不释放。
例如:
void f(int n)
{
static int a=0;
a++;
printf("第%d次调用 a=%d\n",n,a);
}
void main()
{
f(1);
f(2);
f(3);
}
运行结果
第1次调用 a=1
第2次调用 a=2
第3次调用 a=3
我们可以试着用静态局部变量简单计算1~n的阶乘
#include<stdio.h>
int fact(int n)
{
static int f = 1; //定义静态局部变量,初始化为1
f = f * n;
return f;
}
int main()
{
int i,n;
scanf("%d",&n);
for (i=1; i<= n;i++)
printf("%d!=%d\n",i,fact(n));
return 0;
}
在fact函数中,每次函数调用结束后,f将保留上次计算的值,再乘以i,即为i的阶乘。
静态局部变量还有以下特点:
- 静态局部变量与全局变量一样函数编译阶段分配内存,只进行一次初始化。如果定义没有赋初值,系统会自动给其赋值,数值型赋0,字符型赋空字符。
- 虽然静态局部变量一直存在,但它们仅能在定义它们的函数内使用。
3、寄存器变量
在程序运行中如果某些变量被频繁访问,则必须多次访问内存。众所周知,寄存器中的数据访问速度要远远快于内存中的访问速度。如果把通用寄存器分配给被频繁访问的变量,将大大提高程序运行效率。这种变量被称为寄存器变量,用关键字register做储存类型说明。
定义寄存器变量的一般形式如下
register int m;
让我们试着用寄存器变量写一个冒泡排序
main()
{
int a[]={6,5,9,8,7,3};
int i,k;
register int j;
for(i=0;i<=5;i++)
{
for(j=0;j<5-i;j++)
{
if(a[j]>a[j+1])
{
k=a[j];
a[j]=a[j+1];
a[j+1]=k;
}
}
}
for(i=0;i<=5;i++)
printf("%d",a[i]);
return 0;
}
变量j,在程序运行时被频繁访问,将它定义为寄存器变量,访问速度比普通变量快。
特别说明:
- 受硬件限制,一个函数中声明的寄存器变量只能有2到3个,多出的会被系统转换为自动变量。
- 由于寄存器长度的限制,寄存器变量只能是int、short、char或指针型。
- 只有自动局部变量可以声明为寄存器变量。
- 寄存器变量的分配方式是动态的,静态变量不能声明为寄存器变量。