weidagang2046的专栏

物格而后知致
随笔 - 8, 文章 - 409, 评论 - 101, 引用 - 0
数据加载中……

C变量与函数

7.4   内部变量与外部变量

C语言中所有的变量都有自己的作用域。变量说明的位置不同,其作用域也不同,据此将C语言中的变量分为内部变量和外部变量。

7.4.1  内部变量

7.4.2  外部变量

7.4.1  内部变量

在一个函数内部说明的变量是内部变量,它只在该函数范围内有效。

也就是说,只有在包含变量说明的函数内部,才能使用被说明的变量,在此函数之外就不能使用这些变量了。所以内部变量也称局部变量

例如:

int f1(int a)     /*函数f1*/

    {  int b,c

        ……

    }                  /*a,b,c作用域:仅限于函数f1()*/

int f2(int x)     /*函数f2*/

   {  int y,z     

 ……

   }           /*x,y,z作用域:仅限于函数f2()*/

main()

    { int m,n

       ……

    }                  /*m,n作用域:仅限于函数main()*/

关于局部变量的作用域还要说明以下几点:

1.主函数main()中定义的内部变量,也只能在主函数中使用,其它函数不能使用。同时,主函数中也不能使用其它函数中定义的内部变量。因为主函数也是一个函数,与其它函数是平行关系。这一点是与其它语言不同的,应予以注意。

2.形参变量也是内部变量,属于被调用函数;实参变量,则是调用函数的内部变量。

3.允许在不同的函数中使用相同的变量名,它们代表不同的对象,分配不同的单元,互不干扰,也不会发生混淆。

4.在复合语句中也可定义变量,其作用域只在复合语句范围内。

7.4.2  外部变量

在函数外部定义的变量称为外部变量。以此类推,在函数外部定义的数组就称为外部数组。

外部变量不属于任何一个函数,其作用域是:从外部变量的定义位置开始,到本文件结束为止。

外部变量可被作用域内的所有函数直接引用,所以外部变量又称全局变量。

    [案例7.9]  输入长方体的长(l)、宽(w)、高(h),求长方体体积及正、侧、顶三个面的面积。

/*案例代码文件名:AL7_9.C*/

/*功能:利用全局变量计算长方体的体积及三个面的面积*/

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,l,w,h;

            clrscr();

            printf("\ninput length,width and height ");

            scanf("%d%d%d",&l,&w,&h);

            v=vs(l,w,h);

           printf("v=%d    s1=%d    s2=%d    s3=%d\n",v,s1,s2,s3);

           getch();

          }                                                              [程序演示]

对于全局变量还有以下几点说明:

1)外部变量可加强函数模块之间的数据联系,但又使这些函数依赖这些外部变量,因而使得这些函数的独立性降低。

从模块化程序设计的观点来看这是不利的,因此不是非用不可时,不要使用外部变量。

2)在同一源文件中,允许外部变量和内部变量同名。在内部变量的作用域内,外部变量将被屏蔽而不起作用。

3)外部变量的作用域是从定义点到本文件结束。如果定义点之前的函数需要引用这些外部变量时,需要在函数内对被引用的外部变量进行说明。外部变量说明的一般形式为:

extern  数据类型  外部变量[,外部变量2……]

注意:外部变量的定义和外部变量的说明是两回事。外部变量的定义,必须在所有的函数之外,且只能定义一次。而外部变量的说明,出现在要使用该外部变量的函数内,而且可以出现多次。

[案例7.10]  外部变量的定义与说明。

/*案例代码文件名:AL7_10.C*/

int vs(int xl,int xw)

    { extern int xh                  /*外部变量xh的说明*/

       int v

       v=xl*xw*xh                 /*直接使用外部变量xh的值*/

       return v

    }

main()

    {  extern int xw,xh           /*外部变量的说明*/

        int xl=5                        /*内部变量的定义*/

        printf("xl=%d,xw=%d,xh=%d\nv=%d",xl,xw,xh,vs(xl,xw))

    }

int xl=3,xw=4,xh=5            /*外部变量xlxwxh的定义*/

                                                        [程序演示]

7.5   内部函数和外部函数

        当一个源程序由多个源文件组成时,C语言根据函数能否被其它源文件中的函数调用,将函数分为内部函数和外部函数。

7.5.1  内部函数(又称静态函数)

7.5.2  外部函数

7.5.3  多个源程序文件的编译和连接

7.5.1  内部函数(又称静态函数)

如果在一个源文件中定义的函数,只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用,这种函数称为内部函数。

定义一个内部函数,只需在函数类型前再加一个“static”关键字即可,如下所示:

static  函数类型  函数名(函数参数表)

                {……}

关键字“static”,译成中文就是静态的,所以内部函数又称静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件。

使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名,因为同名也没有关系。

7.5.2  外部函数

外部函数的定义:在定义函数时,如果没有加关键字“static”,或冠以关键字“extern”,表示此函数是外部函数:

[extern]  函数类型  函数名(函数参数表)

                       {……}

调用外部函数时,需要对其进行说明:

[extern]  函数类型  函数名(参数类型表)[,函数名2(参数类型表2)……]

[案例7.11]  外部函数应用。

1)文件mainf.c

main()

{  extern void input(…),process(…),output(…);         

    input(…);  process(…);  output(…);

}

2)文件subf1.c

……

extern void input(……)                           /*定义外部函数*/

   {……}

3)文件subf2.c

……

extern void process(……)                      /*定义外部函数*/

   {……}

4)文件subf3.c

……

extern void output(……)                        /*定义外部函数*/

   {……}

7.5.3  多个源程序文件的编译和连接

1)一般过程

编辑各源文件 创建Project(项目)文件 设置项目名称 编译、连接,运行,查看结果。

2)创建Project(项目)文件

用编辑源文件相同的方法,创建一个扩展名为.PRJ的项目文件:该文件中仅包括将被编译、连接的各源文件名,一行一个,其扩展名.C可以缺省;文件名的顺序,仅影响编译的顺序,与运行无关。

注意:如果有某个(些)源文件不在当前目录下,则应在文件名前冠以路径

3设置项目名称

打开菜单,选取ProjectProject name,输入项目文件名即可。

4)编译、连接,运行,查看结果

与单个源文件相同。编译产生的目标文件,以及连接产生的可执行文件,它们的主文件名,均与项目文件的主文件名相同。

注意:当前项目文件调试完毕后,应选取ProjectClear project,将其项目名称从“Project name”中清除(清除后为空)。否则,编译、连接和运行的,始终是该项目文件!

5)关于错误跟踪

缺省时,仅跟踪当前一个源程序文件。如果希望自动跟踪项目中的所有源文件,则应将OptionsEnvironmentMessage Tracking开关置为“All files ”:连续按回车键,直至“All files”出现为止。此时,滚动消息窗口中的错误信息时,系统会自动加载相应的源文件到编辑窗口中。

也可关闭跟踪(“Message Tracking”置为“Off”)。此时,只要定位于感兴趣的错误信息上,然后回车,系统也会自动将相应源文件加载到编辑窗口中。

7.6   变量的动态存储与静态存储简介

在C语言中,对变量的存储类型说明有以下四种:自动变量(auto)、寄存器变量(register)、外部变量(extern)、静态变量(static)。自动变量和寄存器变量属于动态存储方式,外部变量和静态内部变量属于静态存储方式。

7.6.1  内部变量的存储方式

7.6.2  外部变量的存储方式

7.6.1  内部变量的存储方式

1.静态存储──静态内部变量

1)定义格式: static  数据类型  内部变量表;

2)存储特点

1)静态内部变量属于静态存储。在程序执行过程中,即使所在函数调用结束也不释放。换句话说,在程序执行期间,静态内部变量始终存在,但其它函数是不能引用它们的。

2)定义但不初始化,则自动赋以""(整型和实型)或'\0'(字符型);且每次调用它们所在的函数时,不再重新赋初值,只是保留上次调用结束时的值!

3)何时使用静态内部变量

1)需要保留函数上一次调用结束时的值。

2)变量只被引用而不改变其值。

2.动态存储──自动局部变量(又称自动变量)

1)定义格式:[auto]  数据类型  变量表        

2)存储特点

1)自动变量属于动态存储方式。在函数中定义的自动变量,只在该函数内有效;函数被调用时分配存储空间,调用结束就释放。

在复合语句中定义的自动变量,只在该复合语句中有效;退出复合语句后,也不能再使用,否则将引起错误。

2)定义而不初始化,则其值是不确定的。如果初始化,则赋初值操作是在调用时进行的,且每次调用都要重新赋一次初值。

3)由于自动变量的作用域和生存期,都局限于定义它的个体内(函数或复合语句),因此不同的个体中允许使用同名的变量而不会混淆。即使在函数内定义的自动变量,也可与该函数内部的复合语句中定义的自动变量同名。

建议:系统不会混淆,并不意味着人也不会混淆,所以尽量少用同名自动变量!

[案例7.13]自动变量与静态局部变量的存储特性。

/*案例代码文件名:AL7_13.C*/

void  auto_static(void)

   {  int var_auto=0;               /*自动变量:每次调用都重新初始化*/

       static int var_static=0;              /*静态局部变量:只初始化1*/

       printf(“var_auto=%d, var_static=%d\n”, var_auto, var_static);

       ++var_auto;

       ++var_static;

     }

main()

     {  int i;

       for(i=0; i<5; i++) auto_static();

     }                                                               [程序演示]

3.寄存器存储──寄存器变量

一般情况下,变量的值都是存储在内存中的。为提高执行效率,C语言允许将局部变量的值存放到寄存器中,这种变量就称为寄存器变量。定义格式如下:

          register   数据类型   变量表;

1)只有局部变量才能定义成寄存器变量,即全局变量不行。

2)对寄存器变量的实际处理,随系统而异。例如,微机上的MSCTC 将寄存器变量实际当作自动变量处理。

3)允许使用的寄存器数目是有限的,不能定义任意多个寄存器变量。

7.6.2  外部变量的存储方式

外部变量属于静态存储方式:

1)静态外部变量──只允许被本源文件中的函数引用

其定义格式为:  static  数据类型  外部变量表;

2)非静态外部变量──允许被其它源文件中的函数引用

定义时缺省static关键字的外部变量,即为非静态外部变量。其它源文件中的函数,引用非静态外部变量时,需要在引用函数所在的源文件中进行说明:

extern  数据类型  外部变量表;

注意:在函数内的extern变量说明,表示引用本源文件中的外部变量!而函数外(通常在文件开头)的extern变量说明,表示引用其它文件中的外部变量。

静态局部变量和静态外部变量同属静态存储方式,但两者区别较大:

1)定义的位置不同。静态局部变量在函数内定义,静态外部变量在函数外定义。

2)作用域不同。静态局部变量属于内部变量,其作用域仅限于定义它的函数内;虽然生存期为整个源程序,但其它函数是不能使用它的。

静态外部变量在函数外定义,其作用域为定义它的源文件内;生存期为整个源程序,但其它源文件中的函数也是不能使用它的。

    3)初始化处理不同。静态局部变量,仅在第1次调用它所在的函数时被初始化,当再次调用定义它的函数时,不再初始化,而是保留上1次调用结束时的值。而静态外部变量是在函数外定义的,不存在静态内部变量的重复初始化问题,其当前值由最近1次给它赋值的操作决定。

务必牢记:把局部变量改变为静态内部变量后,改变了它的存储方式,即改变了它的生存期。把外部变量改变为静态外部变量后,改变了它的作用域,限制了它的使用范围。因此,关键字“static”在不同的地方所起的作用是不同的。

from: http://other.mblogger.cn/posaidong/archive/07192005.aspx

posted on 2005-08-11 09:41 weidagang2046 阅读(532) 评论(0)  编辑  收藏 所属分类: C/C++


只有注册用户登录后才能发表评论。


网站导航: