变量的作用范围
C语言按变量的作用范围可以将变量可分为局部变量和全局变量。
局部变量
定义:不管是主函数还是其他函数,在函数内声明的变量(包括函数参数)统称为局部变量。 | |
特点:是随函数的调用而生成,函数的调用结束而释放。 | |
作用:作用范围是定义它的函数,只在定义它的作用域内有效,当退出作用域时,其储存空间被释放。而且所有定义过的变量都是局部变量。 |
例如:
int fl(int a)
{
int b,c;
...
} /*a,b,c作用域:仅限于函数fl()中*/
int f2(int x)
{
int y,z;
...
} /*x,y,z作用域:仅限于函数f2()中*/
main()
{
int m,n;
...
} /*m,n作用域:仅限于函数main()中*/
局部变量的作用域的说明:
(1)形参变量也是局部变量,属于被调函数;实参变量,则是调用函数的局部变量。 | |
(2)在复合语句中也可以定义局部变量,其作用域只在复合语句范围内。 | |
(3)主函数main()中定义的局部变量,也只能在主函数中使用,其他函数不能使用。同时,主函数也不能使用其他函数中定义的局部函数。因为主函数也是一个函数,与其他函数是平行关系。这一点是与其他语言不同的,应予以注意。 |
全局变量
定义:函数外定义的变量称为全局变量。全局变量可以被定义它的文件中的所有函数使用。 | |
作用:其作用域是整个源程序。在函数中使用全局变量,一般应作全局变量说明。 | |
特点:全局可视,任何一个函数都可以访问和更改变量值。.内存地址固定,读写效率高。 |
注意:如果定义了与全局变量同名的局部变量,则局部变量优先。
#include<stdio.h>
int s1,s2,s3;
int vs(int a,int b,int c)
{
int v;
v=a*b*c;s1=a*b;s2=b*c;s3=a*c;
return v;
}
main()
{
int v,1,w,h;
printf("\ninput length,width and height:");
v=vs(1,w,h);
printf("v=%d s1=%d s2=%d s3=%d\n",v,s1,s2,s3);
}
结果输出:
input length,width and height:10,6,5
v=300 s1=60 s2=30 s3=50
程序说明:
1,第2行定义整型全局变量是,s1,s2和s3;
2 , 第3~8行定义函数vs,计算长方体的体积和三个面的面积。
3,第11~13行定义局部整行变量v,1,w,和h并通过键盘输入进行初始化。
4,第14行调用函数vs,计算长方体的体积和三个面的面积,函数的参数遵循“单向值传递”的法则,所以局部变量v,1,w和h只能将值传递给vs形参,而形参却不能改变实参的值,但在函数vs中将计算结果赋值给三个全局变量s1,s2和s3,全局变量在整个程序中都是可见并有效的,程序中任何一个地方对全局变量的操作都可以改变其值。
全局变量的说明:
1.全局变量可加强函数模块之间的数据联系,但是又使这些函数依赖这些全局变量,因而使得这些函数的独立性降低。 | |
从模块化 程序设计的观点来看这是不利的,因此不是非用不可时,不要使用全局变量。 | |
1.全局变量的作用域是从定义点道文件结束。如果定义点之前的函数需要引用这些全局变量,需要在函数内对被引用的全局变量进行说明。全局变量说明的一般形式为: extern数据类型 全局变量[.全局变量 2......]; 外部变量使用关键字“extern”定义,在函数体之外定义。存放在静态储存区。 |
全局变量的优点:
(1)增加了各函数间数据传送的渠道。特别是函数返回值通常仅限于一个,在很多场合不能满足使用要求。此时利用全局变量,可以得到更多的数据处理结果。
(2)利用全局变量可以减少函数实参与形参的个数。可以减少变量的个数,减少由于实际参数和形式参数的数据传递带来的时间消耗。
全局变量的缺点:
(3)全局变量使函数的代码可读性降低。由于多个函数都可能使用全局变量,函数执行时全局变量的值可能随时发生变化,对于程序的查错和调试都非常不利。因此,如果不是万不得已,最好不要使用全局变量。
变量的存储类别
[存储类型]类型说明符变量名表列;
变量占用内存单元的时间称为“生存期”,变量的生存期是由变量的存储位置决定的
内存储器:内存中供用户使用的存储空间分为代码区与数据区两个部分。
动态存储方式:是在程序运行期间根据需要进行动态的分配存储空间的方式。
比如extern u8 tpwakeupswitch;extern int tpwakeupswitch_read();一定要加上返回类型,亲身碰到没有返回类型,引用过来的变量是很奇怪的值。
四)register:register称为寄存器变量。它只能用于整型和字符型变量。定义符register说明的变量被存储在CPU的寄存器中,定义一个整型寄存器变量可写成: register int a;
对于以上四种数据的存储位置:register变量存在CPU的寄存器中;auto类型变量存在内存的栈;static型的局部变量和全局变量以及extern型变量(即全局变量),存在于内存的静态区。

1,自动存储类型
定义:
自动变量又称动态变量,在程序执行过程中,需要使用它时才分配存储单元,使用完立即释放。
关键字auto表示变量是自动存储类型,自动存储类型的变量具有动态性。存储在堆区和栈区的变量,随函数调用而生成,随函数调用结束而释放,C语言从存储的角度称这些变量为自动变量。
动态变量的定义格式:
auto 数据类型 变量名;/* 关键字 auto 可缺省*/
例如,定义a,b,c为整型自动存储类别变量:
auto int a,b,c
外部变量:说明外部变量的关键字为extern,外部变量有两种情形:
1.本文件(源程序)中的全局变量先使用后说明的,使用前要说明为外部变量。
2.其他文件中未用static说明的全局变量。
特点:
外部变量一定是全局变量。 | |
外部变量的存储类型是静态类型,具有缺省初值0. |
#include<stdio.h>
main()
{
int a=0;
register int i;
for(i=1;i<10;i++)
{
a+=i;
printf("%d",a);
}
printf("\n");
}
运行结果:
a.out
1 3 6 10 15 21 28 36 45
注意:由于寄存器变量属于动态存储方式,故只有局部自动变量和形式参数才可以定义为寄存器变量。 | |
凡需要采用静态存储方式的量不能定义为寄存器变量。 | |
由于CPU中寄存器的个数是有限的,因此使用寄存器变量的个数也是有限的。 | |
定义成寄存器类型的变量未必能按寄存器变量使用,还是当着一般变量来使用,这个取决于编译器。 |
特点:具有缺省的初值0,有全局和局部之分。当static修饰的是局部变量的时候,说明该变量一直存在,但是该变量只能在该作用域内使用(静态变量的记忆功能)。
当static修饰的是全局变量的时候,表示该全局变量只能在本文件(源程序)中使用,其他文件是不允许引用被static修饰的全局变量的。一般的全局变量虽然不是静态变量,但像静态变量一样具有缺省的初值为0.静态数组变量同样具有缺省的初值为0,如static int a[10];则数组a的每个元素的值都为0.
静态局部变量和非局部变量的本质区别是存储类不同:静态局部变量分配在数据段/bss段上,而非静态局部变量分配在栈上。
注意:
1.局部变量默认auto型 | |
2.register型变量个数受限,且不能为long,double,float型。 | |
3.局部static变量具有全局寿命和局部可见性,还具有可继承型。 | |
4.extern不是变量定义,可扩展外部变量作用域。 |