c语言复合语句和函数内部 c语言复合语句的作用( 二 )

if(a0){
s=a+a;
p=a*a;
}
printf("s=%d p=%d\n",s,p);
}
{ auto int a;
printf("\ninput a number:\n");
scanf("%d",a);
if(a0){
auto int s,p;
s=a+a;
p=a*a;
}
printf("s=%d p=%d\n",s,p);
}
s,p是在复合语句内定义的自动变量,只能在该复合语句内有效 。而程序的第9行却是退出复合语句之后用printf语句输出s,p的值,这显然会引起错误 。
3. 由于自动变量的作用域和生存期都局限于定义它的个体内( 函数或复合语句内) ,  因此不同的个体中允许使用同名的变量而不会混淆 。即使在函数内定义的自动变量也可与该函数内部的复合语句中定义的自动变量同名 。例5.14表明了这种情况 。
[例5.14]
main()
{
auto int a,s=100,p=100;
printf("\ninput a number:\n");
scanf("%d",a);
if(a0)
{
auto int s,p;
s=a+a;
p=a*a;
printf("s=%d p=%d\n",s,p);
}
printf("s=%d p=%d\n",s,p);
}
本程序在main函数中和复合语句内两次定义了变量s,p为自动变量 。按照C语言的规定 , 在复合语句内,应由复合语句中定义的s,p起作用,故s的值应为a+ a,p的值为a*a 。退出复合语句后的s,p 应为main所定义的s,p,其值在初始化时给定,均为100 。从输出结果可以分析出两个s和两个p虽变量名相同,但却是两个不同的变量 。
4. 对构造类型的自动变量如数组等,不可作初始化赋值 。
二、外部变量外部变量的类型说明符为extern 。
在前面介绍全局变量时已介绍过外部变量 。这里再补充说明外部变量的几个特点:
1. 外部变量和全局变量是对同一类变量的两种不同角度的提法 。全局变是是从它的作用域提出的 , 外部变量从它的存储方式提出的,表示了它的生存期 。
2. 当一个源程序由若干个源文件组成时 ,  在一个源文件中定义的外部变量在其它的源文件中也有效 。例如有一个源程序由源文件F1.C和F2.C组成: F1.C
int a,b; /*外部变量定义*/
char c; /*外部变量定义*/
main()
{
……
}
F2.C
extern int a,b; /*外部变量说明*/
extern char c; /*外部变量说明*/
func (int x,y)
{
……
}
在F1.C和F2.C两个文件中都要使用a,b,c三个变量 。在F1.C文件中把a,b,c都定义为外部变量 。在F2.C文件中用extern把三个变量说明为外部变量,表示这些变量已在其它文件中定义,并把这些变量的类型和变量名,编译系统不再为它们分配内存空间 。对构造类型的外部变量 ,  如数组等可以在说明时作初始化赋值,若不赋初值,则系统自动定义它们的初值为0 。
三、静态变量
静态变量的类型说明符是static 。静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量 ,  例如外部变量虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成为静态外部变量,或称静态全局变量 。对于自动变量,前面已经介绍它属于动态存储方式 。但是也可以用static定义它为静态自动变量,或称静态局部变量,从而成为静态存储方式 。
由此看来,一个变量可由static进行再说明,并改变其原有的存储方式 。
1. 静态局部变量
在局部变量的说明前再加上static说明符就构成静态局部变量 。
例如:
static int a,b;
static float array[5]={1,2,3,4,5};
静态局部变量属于静态存储方式,它具有以下特点:
(1)静态局部变量在函数内定义,但不象自动变量那样 , 当调用时就存在 , 退出函数时就消失 。静态局部变量始终存在着,也就是说它的生存期为整个源程序 。

推荐阅读