(1) 主函数中定义的变量 (m,n) 也只在主函数中有效,而不因为在主函数中定义而在整个文件或程序中有效。主函数也不能使用其他函数中定义的变量。
(2) 不同函数中可以使用相同名字的变量,它们代表不同的对象,互不干扰。例如,在 fl 函数中定义了变量 c, 倘若在 f2函数中也定义变量 c, 它们在内存中占不同的单元,互不混淆。
(3) 形式参数也是局部变量。例如fl 函数中的形参 a, 也只在 fl 函数中有效。其他函数可以调用 fl 函数,但不能引用 fl 函数的形参a。
(4) 在一个函数内部,可以在复合语句中定义变量,这些变量只在本复合语句中有效,这种复合语句也称为“分程序”或“程序块”。
(1) 设置全局变量的作用是增加了函数间数据联系的渠道。由于同一文件中的所有函数都能引用全局变量的值,因此如果在一个函数中改变了全局变量的值,就能影响到其他函数,相当于各个函数间有直接的传递通道。由于函数的调用只能带回一个返回值,因此有时可以利用全局变量增加函数间的联系渠道,通过函数调用能得到一个以上的值。
**为了便于区别全局变量和局部变量,在C程序设计人员中有一个不成文的约定(但非规定),将全局变量名的笫1个字母用大写表示。
(2) 建议不在必要时不要使用全局变最,原因如下。
①全局变量在程序的全部执行过程中都占用存储单元,而不是仅在需要时才开辟单元。
②它使函数的通用性降低了,因为函数在执行时要依赖于其所在的外部变量。如果将一个函数移到另一个文件中,还要将有关的外部变量及其值一起移过去。但若该外部变量与其他文件的变量同名时,就会出现问题,降低了程序的可靠性和通用性。在程序设计中,在划分模块时要求模块的“内聚性”强、与其他模块的”耦合性”弱。即模块的功能要单一(不要把许多互不相干的功能放到一个模块中),与其他模块的相互影响要尽量少,而用全局变量是不符合这个原则的。一般要求把C程序中的函数做成一个封闭体,除了可以通过“实参—形参”的渠道与外界发生联系外,没有其他渠道。这样的程序移植性好,可读性强。
③使用全局变量过多,会降低程序的清晰性,人们往往难以清楚地判断出每个瞬时各个外部变量的值。在各个函数执行时都可能改变外部变量的值,程序容易出错。因此,要限制使用全局变量。
(3) 如果在同一个源文件中,外部变量与局部变量同名,则在局部变量的作用范围内,外部变扯被“屏蔽”,即它不起作用。
从变量的作用域(即从空间)角度来分,可以分为全局变量和局部变量;
从另一个角度,从变量值存在的时间(即生存期)角度来分,可以分为静态存储方式和动态存储方式。
所谓静态存储方式是指在程序运行期间由系统分配固定的存储空间的方式,而动态存储方式则是在程序运行期间根据需要进行动态的分配存储空间的方式。
内存中的供用户使用的存储空间的情况。这个存储空间可以分为三部分:
(1) 程序区;
(2) 静态存储区;
(3) 动态存储区。
数据分别存放在静态存储区和动态存储区中。全局变量全部存放在静态存储区中,在程序开始执行时给全局变量分配存储区,程序执行完毕就释放,在程序执行过程中它们占据固定的存储单元,而不是动态地进行分配和释放。
在动态存储区中存放以下数据
①函数形式参数。在调用函数时给形参分配存储空间。
②自动变量(未加 static 声明的局部变量)。
③函数调用时的现场保护和返回地址等。
关键字"auto" 可以省略, auto 不写则隐含确定为“自动存储类别“,它属于动态存储方式。程序中大多数变量属于自动变量。前面介绍的函数中定义的变量都没有声明为 auto, 其实都隐含指定为自动变量。
eg:
auto int b,c=3;
等价于
int b,c=3;
有时希望函数中的局部变量的值在函数调用结束后不消失而保留原值,即其占用的存储单元不释放,在下一次该函数调用时,该变量已有值,就是上一次函数调用结束时的值。这时就应该指定该局部变量为“静态局部变量“,用关键字 static 进行声明。
#include
void main()
{
int f(int);
int a=2,i;
for(i=O;i<3;i++)
printf("%d ",f(a));
}
int f(int a)
{
auto int b=O;
static int c=3;
b=b+l;
c=c+l;
return(a+b+c);
}
运行结果为:
7 8 9
在第1次调用f函数时,b的初值为0,c 的初值为3,第1次调用结束时, b=1,c=4,a+b+c=7。由于c是静态局部变量,在函数调用结束后,它并不释放,仍保留c=4。在第2次调用f函数时,b的初值为0,c的初值为 4( 上次调用结束时的值) 。
一般情况下,变量(包括静态存储方式和动态存储方式)的值是存放在内存中的。当程序中用到哪一个变量的值时,由控制器发出指令将内存中该变量的值送到运算器中。经过运算器进行运算,如果需要存数,再从运算器将数据送到内存存放。
如果有一些变量使用频繁(例如,在一个函数中执行 10000 次循环,每次循环中都要引用某局部变量),则为存取变量的值要花费不少时间。为提高执行效率,C语言允许将局部变量的值放在CPU中的寄存器中,需要用时直接从寄存器取出参加运算,不必再到内存中去存取。由于对寄存器的存取速度远高于对内存的存取速度,因此这样做可以提高执行效率。这种变量叫做寄存器变量,用关键字 register 作声明。
** 通常情况下,不建议使用register变量,该变量只是向系统建议将该值存放在寄存器上,如果存放在寄存器上,不能取该值的地址。
外部变量是在函数的外部定义的全局变量,它的作用域是从变量的定义处开始,到本程序文件的末尾。在此作用域内,全局变量可以为程序中各个函数所引用。编译时将外部变扯分配在静态存储区。
有时需要用 extern 来声明外部变量,以扩展外部变量的作用域。
用1个简单的例子来说明这种引用。
eg:用extern 将外部变社的作用域扩展到其他文件
本程序的作用是给定b的值,输人a和m,求a*和a的m次方的值。
文件filel.c中的内容为:
#include < stdio. h>
int A; //定义外部变量
void main()
{
int power(int); //函数声明
int b=3,c,d,m;
printf("enter the number a and its power m: \n");
scanf("%d,%d",&A,&m);
c=A * b;
printf("%d * %d= %d\n" ,A,b, c);
d=power(m);
printf("%d * * %d= %d\n",A,m,d);
}
文件 file2.c中的内容为:
extern A; //声明A为一个已定义的外部变量
int power(int n)
{
int i,y=l;
for(i = l ;i<=n;i++)
y *= A;
return(y);
}
可以看到,file2.c文件中的开头有一个extern声明,它声明在本文件中出现的变量A是一个已经在其他文件中定义过的外部变量,本文件不必再为它分配内存。
本来外部变量A的作用域是file1.c, 但现在用extern声明将其作用域扩大到 file2.c文件。假如程序有5个源文件,在一个文件中定义外部整型变量 A, 其他4个文件都可以引用 A,但必须在每一个文件中都加上一个"extern A;" 声明。在各文件经过编译后,将各目标文件连接成一个可执行的目标文件。