标题:
C基础教程 第八章 函 数(下)
[打印本页]
作者:
苹果也疯狂
时间:
2011-10-21 12:14
标题:
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
;
/*
外部变量
xl
、
xw
、
xh
的定义
*/
[
程序演示
]
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
)设置项目名称
打开菜单,选取
Project
/
Project name
,输入项目文件名即可。
(
4
)编译、连接,运行,查看结果
与单个源文件相同。编译产生的目标文件,以及连接产生的可执行文件,它们的主文件名,均与项目文件的主文件名相同。
注意:当前项目文件调试完毕后,应选取
Project
/
Clear project
,将其项目名称从“
Projectname
”中清除(清除后为空)。否则,编译、连接和运行的,始终是该项目文件!
(
5
)关于错误跟踪
缺省时,仅跟踪当前一个源程序文件。如果希望自动跟踪项目中的所有源文件,则应将
Options
/
Environment
/
Message 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
"
(整型和实型)或
'\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
)对寄存器变量的实际处理,随系统而异。例如,微机上的
MSC
和
TC
将寄存器变量实际当作自动变量处理。
(
3
)允许使用的寄存器数目是有限的,不能定义任意多个寄存器变量。
7.6.2
外部变量的存储方式
外部变量属于静态存储方式:
(
1
)静态外部变量──只允许被本源文件中的函数引用
其定义格式为:
static
数据类型
外部变量表;
(
2
)非静态外部变量──允许被其它源文件中的函数引用
定义时缺省
static
关键字的外部变量,即为非静态外部变量。其它源文件中的函数,引用非静态外部变量时,需要在引用函数所在的源文件中进行说明:
extern
数据类型
外部变量表;
注意:在函数内的
extern
变量说明,表示引用本源文件中的外部变量!而函数外(通常在文件开头)的
extern
变量说明,表示引用其它文件中的外部变量。
静态局部变量和静态外部变量同属静态存储方式,但两者区别较大:
(
1
)定义的位置不同。静态局部变量在函数内定义,静态外部变量在函数外定义。
(
2
)作用域不同。静态局部变量属于内部变量,其作用域仅限于定义它的函数内;虽然生存期为整个源程序,但其它函数是不能使用它的。
静态外部变量在函数外定义,其作用域为定义它的源文件内;生存期为整个源程序,但其它源文件中的函数也是不能使用它的。
(
3
)初始化处理不同。静态局部变量,仅在第
1
次调用它所在的函数时被初始化,当再次调用定义它的函数时,不再初始化,而是保留上
1
次调用结束时的值。而静态外部变量是在函数外定义的,不存在静态内部变量的“重复”初始化问题,其当前值由最近
1
次给它赋值的操作决定。
务必牢记:把局部变量改变为静态内部变量后,改变了它的存储方式,即改变了它的生存期。把外部变量改变为静态外部变量后,改变了它的作用域,限制了它的使用范围。因此,关键字“
static
”在不同的地方所起的作用是不同的。
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0