- 局部变量和全局变量
- 局部变量:在一个函数内部定义的变量是局部变量(内部变量),它只在本函数范围内有效,也就是说只有在本函数内才能使用它们,在此函数以外是不能使用这些变量的。(注:(1) 主函数中定义的变量(m,n)也只在主函数中有效,而不因为在主函数中定义而在整个文件或程序中有效。主函数也不能使用其他函数中定义的变量。(2) 不同函数中可以使用相同名字的变量,它们代表不同的对象,互不干扰。例如, 上面在f1函数中定义了变量b和c,倘若在f2函数中也定义变量b和c,它们在内存中占不同的单元,互不混淆。(3) 形式参数也是局部变量。(4) 在一个函数内部,可以在复合语句中定义变量,这些变量只在本复合语句中有效,这种复合语句也称为“分程序”或“程序块”。)
- 全局变量:在函数之外定义的变量称为全局变量(外部变量)。全局变量可以为本文件中其他函数所共用。它的有效范围为从定义变量的位置开始到本源文件结束。见例1.
//例1
/#include <stdio.h>int s1,s2,s3; //全局变量s1, s2, s3
int vs( int a,int b,int c)
{
int v; //局部变量 v
v = abc;
s1 = ab;
s2 = bc;
s3 = a*c;
return v;
}void main()
{
int v,l,w,h; //局部变量v, l, w, h
printf("\ninput length,width and height\n");
scanf("%d%d%d",&l,&w,&h); //long, width, high
v = vs(l,w,h);
printf("\nv=%d,s1=%d,s2=%d,s3=%d\n",v,s1,s2,s3);
}
在可以不使用全局变量的情况下不建议使用全局变量,因为:
(1)全局变量在程序的全部执行过程中都占用存储单元,而不是仅在需要时才开辟单元。
(2)使用全局变量过多,会降低程序的清晰性,人们往往难以清楚地判断出每个瞬时各个外部变量的值。在各个函数执行时都可能改变外部变量的值,程序容易出错。因此,要限制使用全局变量。
(3)它使函数的通用性降低了,因为函数在执行时要依赖于其所在的外部变量。如果将一个函数移到另一个文件中,还要将有关的外部变量及其值一起移过去。但若该外部变量与其他文件的变量同名时,就会出现问题,降低了程序的可靠性和通用性。一般要求把C程序中的函数做成一个封闭体,除了可以通过“实参——形参”的渠道与外界发生联系外,没有其他渠道。
-
函数的静态存储方式和动态存储方式
2.1静态存储方式:是指在程序运行期间由系统分配固定的存储空间的方式。
2.2动态存储方式:是在程序运行期间根据需要进行动态的分配存储空间的方式。(即调用时分配内存,调用完毕释放内存。)
2.3程序存储空间可以分为三部分:1)程序区;2)静态存储区;3) 动态存储区
2.4 在C语言中每一个变量和函数有两个属性:数据类型(如整型、字符型等)和数据的存储类别(即存储方式)(分为两大类:静态存储类型和动态存储类型。 静态和动态存储类型又细分为,静态存储类型:static变量和extern变量;动态存储类型:auto变量和register变量)。2.5 用static声明局部变量:有时希望函数中的局部变量的值在函数调用结束后不消失而保留原值,即其占用的存储单元不释放,在下一次该函数调用时,该变量已有值,就是上一次函数调用结束时的值。这时就应该指定该局部变量为“静态局部变量”,用关键字static进行声明。见例2。
//例2
/#include <stdio.h>int f(int a)
{
auto int b = 0;
static int c = 3;
b = b + 1; // b == 1 , 1 , 1
c = c + 1; // c == 4 , 5 , 6
return (a+b+c); // 7 , 8 , 9
}void main()
{
int a=2, i;
for(i=0; i < 3; i++)
{
printf("%d\n", f(a));
}
}
//输出: 7
8
9
2.6 静态局部变量的说明(例3)
(1) 静态局部变量属于静态存储类别,在静态存储区内分配存储单元。在程序整个运行期间都不释放。
(2) 对静态局部变量是在编译时赋初值的,即只赋初值一次,在程序运行时它已有初值。以后每次调用函数时不再重新赋初值而只是保留上次函数调用结束时的值。
(3)如在定义局部变量时不赋初值的话,则对静态局部变量来说,编译时自动赋初值0(对数值型变量)或空字符(对字符变量)。
(4) 虽然静态局部变量在函数调用结束后仍然存在,但其他函数是不能引用它的。
//例3
/#include <stdio.h>int fac(int n)
{
static int f = 1;
f = f * n; // 11, 12, 23, 64, 24*5
return (f); // 1, 2, 6, 24, 120
}void main()
{
int i;
for(i=1; i <= 5; i++)
{
printf("%d! = %d\n", i, fac(i)); // 1, 2, 6, 24, 120
}
}
//输出: 1
2
6
24
120
2.7 动态局部变量的说明
(1)自动变量(即动态局部变量)属于动态存储类别,占动态存储区空间而不占静态存储区空间,函数调用结束后即释放。
(2)对自动变量赋初值,不是在编译时进行的,而是在函数调用时进行,每调用一次函数重新给一次初值,相当于执行一次赋值语句。
(3)对自动变量来说,如果不赋初值则它的值是一个不确定的值。这是由于每次函数调用结束后存储单元已释放,下次调用时又重新另分配存储单元,而所分配的单元中的值是不确定的。
2.8 register变量:由于对寄存器的存取速度远高于对内存的存取速度, 为提高执行效率,C语言允许将局部变量的值放在CPU中的寄存器中,需要用时直接从寄存器取出参加运算,不必再到内存中去存取。这种变量叫做寄存器变量,用关键字register作声明。见例4
//例4
/#include<stdio.h>
int fac(int n)
{
register int i, f = 1; //定义寄存器变量
for(i=1; i <= n; i++)
{
f *= i;
}
return (f);
}void main()
{
int i;
for(i=1; i <= 15; i++)
{
printf("%d! = %d\n", i, fac(i));
}
}
2.9 extern变量:外部变量即全局变量,它的作用域是从变量的定义处开始,到本程序文件的末尾。在此作用域内,全局变量可以为程序中各个函数所引用。编译时将外部变量分配在静态存储区。有时需要用extern来声明外部变量,以扩展外部变量的作用域。见例5
//例5
/#include <stdio.h>int max(int x, int y)
{
return x > y ? x : y;
}void main()
{
extern A, B; //使用extern关键字定义全局变量
printf("The maximum number is: %d\n", max(A, B));
}
int A = 13, B = -8;
//输出:The maximum number is: 13