变量的作用范围与存储类型

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)利用全局变量可以减少函数实参与形参的个数。可以减少变量的个数,减少由于实际参数和形式参数的数据传递带来的时间消耗。

全局变量的缺点

(1)局变量保存在静态存贮区,程序开始运行时为其分配内存,程序结束释放该内存。与局部变量的动态分配、动态释放相比,生存期比较长,因此过多的全局变量会占用较多的内存单元。
(2)全局变量破坏了函数的封装性能。前面的章节曾经讲过,函数象一个黑匣子,一般是通过函数参数和返回值进行输入输出,函数内部实现相对独立。但函数中 如果使用了全局变量,那么函数体内的语句就可以绕过函数参数和返回值进行存取,这种情况破坏了函数的独立性,使函数对全局变量产生依赖。同时,也降低了该 函数的可移植性。

(3)全局变量使函数的代码可读性降低。由于多个函数都可能使用全局变量,函数执行时全局变量的值可能随时发生变化,对于程序的查错和调试都非常不利。因此,如果不是万不得已,最好不要使用全局变量。



定义:

 C语言中的变量不仅有类型属性,而且还有存储类别的属性。完整的变量定义应该确定它的两种属性:存储类型和数据类型。
 变量定义的完整形式为:
[存储类型]类型说明符变量名表列;

变量占用内存单元的时间称为“生存期”,变量的生存期是由变量的存储位置决定的

 CPU寄存器:CPU寄存器中存储的数据是动态存储类型,不能长期占用。
内存储器:内存中供用户使用的存储空间分为代码区与数据区两个部分。
静态存储方式:是指在程序运行期间分配固定的存储空间的方式。
动态存储方式:是在程序运行期间根据需要进行动态的分配存储空间的方式。
比如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. 
寄存器变量:用关键字register说明的变量是寄存器类型变量。C++编译器江永寄存器类型变量的值存放在CPU的寄存器中,而不是存储器中,从而提高程序运行效率,常用语循环控制。
#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中寄存器的个数是有限的,因此使用寄存器变量的个数也是有限的 
定义成寄存器类型的变量未必能按寄存器变量使用,还是当着一般变量来使用,这个取决于编译器 
静态变量:静态变量的类型说明符是static,属于静态存储方式。
特点:具有缺省的初值0,有全局和局部之分。当static修饰的是局部变量的时候,说明该变量一直存在,但是该变量只能在该作用域内使用(静态变量的记忆功能)。
当static修饰的是全局变量的时候,表示该全局变量只能在本文件(源程序)中使用,其他文件是不允许引用被static修饰的全局变量的。一般的全局变量虽然不是静态变量,但像静态变量一样具有缺省的初值为0.静态数组变量同样具有缺省的初值为0,如static int a[10];则数组a的每个元素的值都为0.
静态局部变量和非局部变量的本质区别是存储类不同:静态局部变量分配在数据段/bss段上,而非静态局部变量分配在栈上。

注意:

1.局部变量默认auto型 
2.register型变量个数受限,且不能为long,double,float型。 
3.局部static变量具有全局寿命和局部可见性,还具有可继承型。 
4.extern不是变量定义,可扩展外部变量作用域。 




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章