收藏 分享(赏)

第八章. 函数.ppt

上传人:dzzj200808 文档编号:3318031 上传时间:2018-10-12 格式:PPT 页数:80 大小:1.85MB
下载 相关 举报
第八章. 函数.ppt_第1页
第1页 / 共80页
第八章. 函数.ppt_第2页
第2页 / 共80页
第八章. 函数.ppt_第3页
第3页 / 共80页
第八章. 函数.ppt_第4页
第4页 / 共80页
第八章. 函数.ppt_第5页
第5页 / 共80页
点击查看更多>>
资源描述

1、第 八 章 函 数,概 述,函数定义的一般形式,函数参数和函数值,函数的调用,函数的嵌套调用,函数的递归调用,数组作为函数参数,局部变量和全局变量,内部函数和外部函数,第八章 函 数,学习要点:掌握函数的定义方法掌握函数的类型和返回值掌握形式参数与实际参数、参数传递掌握函数的正确调用,了解函数的递归调用掌握局部变量和全局变量变量的存储类型,作用域和生存期,假如不模块化,读多少行的程序能让你不头疼? main( )当中能放多少行程序? 假如printf()函数由10行代码替换,那么你见过的程序会成什么样子? 如果所有代码都在main()当中,怎么团队合作? 如果代码都在一个文件中,怎么团队合作?

2、,模块化的优点,模块各司其职 每个模块只负责一件事情,它可以更专心 便于进行单个模块的设计、开发、调试、测试和维护等工作 一个模块一个模块地完成,最后再将它们集成 开发人员各司其职 按模块分配任务,职责明确 并行开发,缩短开发时间 分而治之(Wirth, 1971 ) 信息隐藏(Parnas, 1972),函数(function)和模块(module),函数是C语言中模块化编程的最小单位 可以把每个函数看作一个模块 若干相关的函数可以合并作一个“模块”,第八章 函 数 8.1 概 述一个 C 程序由一个主函数和若干个其它函数构成。程序执行总是从主函数开始,由主函数调用其它函数,其它函数也可以互

3、相调用。,main ( ) fa( ); fb( );,fa( ) f1( ); ,f1( ) ,f3( ) ,fb( ) f2( );f3( ); ,f2( ) ,执行过程,结构框图,结构框图,框图,例 8.1main ( ) printstar ( ) ;print_message ( ) ;printstar ( ) ;printstar ( ) printf ( “ * * * * * * * * * * * * * * * * * n ” ) ;print_message ( ) printf ( “ How do you do ! n ” ) ; ,运行过程示意,main ( )

4、调用函数1 ;调用函数2 ;调用其它函数 ;,函数1 ,函数2 ,C 程序的一般通用结构。,其它函数,说明: 1. 一个C 源程序文件由一个或多个函数组成。以源程序文件为编译单位。2. main( ) 函数由系统定义。3. 函数定义 ,可以互相调用。在其它函数中不能调用 main( ) 函数。4. 函数的种类从用户来看: 标准函数(库函数)用户自定义函数。从形式来看: 无参函数, 有参函数。,不能嵌套,函数定义严禁嵌套 main ( ) printstar ( ) ;printstar ( ) printf (“ * * * * * * n ” ) ; 因大括号位置不当引起 函数定义上的嵌套X

5、X,重点,8.2 函数定义的一般形式一般格式:存储类型 数据类型 函数名( 形式参数表列 ) 声明部分执行语句,现代定义形式,传统定义形式,说明: 1. 数据类型指的是函数的返回值类型。2. 可以定义和使用空函数,空函数定义和使用,int max ( int x , int y ) int z ;z = x y ? x : y ; return ( z ) ;,说明,int max ( x , y ) int x , y ; int z ;z = x y ? x : y ; return ( z ) ; ,说明,空函数的应用 应用:模块设计过程中.int dummy ( ) ,说明,8.3 函

6、数参数和函数值 一、形式参数和实际参数例8.2 main ( ) int a , b, s ;scanf ( “ %d ,%d ” , ,程序中 a , b 为实参; x , y 为形参,函数参数传递演示,main( ) int a, b, s;a=2, b=3;s= sum(a,b);/* 其它处理 */printf(“s=%d”,s); ,int sum(x , y) int x, y; int s;/* 其它处理 */s = x + y ; return (s) ; ,a = 2,b = 3,s = 5,关于形参与实参的说明:1. 形参变量在未出现函数调用时,并不占用内存单元。调用时才为

7、其分配内存单元,且调用结束后所占用内存单元立即释放。2. 实参可以是常量,变量(包括指针变量),数组名(包括数组元素 ) 或表达式等,但应有确定的值。如: max ( 3 , a + b ) ;3. 实参和形参在数据类型和个数上应匹配。4. 实参对形参的数据传递是“值传递”,即单向传递。二者在内存中占据不同的内存单元。在调用函数时,形参的值即使发生变化,也不会改变主调函数的实参值。,实例,形参的值改变 不会改变实参的值 main( ) int a = 3 , b = 4 ;add ( a , b ) ;printf(“%d,%dn”, a, b); add ( int x , int y )

8、x = x + 3 ; y = y + 4 ; 结果为: 3, 4,重点,5. 形参变量和实参变量可以同名。main( ) int a = 3 , b = 4 ;add ( a , b ) ;printf (“%d ,%d n”, a , b ) ;add ( int a , int b ) a = a + 3 ; b = b + 4 ;,3,4,3,4,6,8,a,b,a,b,a,b,输出: 3 , 4,变量或表达式,4. 若确定不需要带回返回值,则可以将函数定义 为:void 型。系统保证不使用函数的返回值。,二、函数的返回值格式: return ( ) ;,说明: 1. 一个函数中允许有

9、多个 return 语句。,2. 函数值的类型应和 return 语句中变量(或表达式)的类型一致。 如不匹配,则以函数类型为准。对于数值型数据可以自动进行类型转换。,3. 若被调函数中无 return 语句,则返回一个不确定值。,一个函数中允许有 多个 return 语句int max ( int x , int y)if ( x y)return ( x ) ;else return ( y ) ;,多个 return,示例,函数返回值隐含的 自动类型转换 main ( ) float a , b , c ;scanf ( “%f ,%f”,类型转换,示例,程序运行,程序运行 输入: 1.

10、5 , 2.5 输出: max is 2,重点,无 return 语句 则返回一个不确定值 main ( ) int a , b;a = printstar ( ) ; /* a,b不确定 */b = print_message ( ) ;printf ( “%d , %d n” , a , b ) ; printstar ( ) printf(“*n”); printstar ( ) printf(“Hello world.n”);,返回不确定值,示例,请找出有错的语句! main ( ) int a , b;a = printstar ( ) ; b = print_message ( )

11、 ;printf ( “%d , %d n” , a , b ) ; void printstar ( ) printf(“*n”); void printstar ( ) printf(“Hello world.n”);,请找错,示例,return 返回 变量或表达式的值 int max ( int x , int y) int z ;z = x y ? x : y ;return ( z ) ; /* 返回变量的值 */int min ( int x , int y )return( x y ? x : y ) ;/* 返回表达式的值 */,说明,8.4 函数的调用 一、一般形式格式: 函

12、数名( 实参表列 ),说明:1. 对无参函数,括号不能省。2. 若有多个实参,则各参数之间应有逗号。3. 实参和形参在个数和类型上要匹配。4. 对实参表列的求值顺序不确定。可从左至右,也可从右至左,视系统而定。如 Turbo C 中就是按从右至左。,实例,main ( ) int i = 2 ;int p ;p = f ( i , +i ) ; printf ( “ %d ” , p ) ; int f ( int a , int b ) int c ; if ( a b ) c = 1 ;else if ( a = = b ) c = 0 ;else c = 1;return ( c ) ;

13、 ,结果说明,结果: 可能是 1 也可能是 0。 因为:按从左至右求值, 则为 f(2,3),即: (ab) p为1按从右至左求值, 则为 f(3,3),即: (a=b) p为 0 若本意按从左至右,则可改为: j = i ;k = +i ;p = f ( j , k ) ; ,补充例:#include “stdio.h”main ( ) char c1 , c2 , c3 ;c1 = getchar ( ) ; c2 = getchar ( ) ;c3 = getchar ( ) ;printf(“%c%c%cn”, putchar(c1) ,putchar(c2) , putchar(c3

14、) ; 输入: abc,输出: cbaabc,printf (“%c%c%cn”, a , b, c ) ;,二、函数的调用方式1. 函数语句作为一条独立的语句完成一定的操作。如例7.1中: printstar ( ) ;2. 函数表达式 出现在表达式中,参与运算。如: c = 2* max ( a , b ) ;3. 函数参数 如: m = max ( a , max ( b , c ) ) ; printf ( “ %d ”, max ( a , b ) ) ;,例 1,在下列几种情况下可以不必作函数声明,三种形式,例3,三、对被调函数的声明(说明)1. 被调函数必须存在。2. 使用库函数

15、时应在文件开头用 #include 命令将调用有关库函数时所需用到的信息包含到源程序中来。3. 对用户自定义函数,一般情况下应在主调函数中对被调函数作声明(说明) ,即函数原型。 作用:在编译阶段对调用函数的合法性进行检查。,对被调函数声明有,函数声明形式 函数类型 函数名( ) 函数类型 函数名(参数类型1,参数类型 2, ) 函数类型 函数名(参数类型1,参数名1,参数类型2 参数名2, ),说明,对被调函数声明形式 1main ( ) float add ( ) ; /* 函数声明形式 1 */float a, b, c;scanf(“%f,%f ”, ,说明,例 2,对被调函数声明形式

16、 2main ( ) float add(float,float) ; /* 函数声明形式 */float a, b, c;scanf(“%f,%f ”, ,说明,对被调函数声明形式 3 main ( ) float add( float a,float b); /* 声明形式3 */float a, b, c;scanf(“%f,%f ”, ,说明,可以不必作函数声明的几种情况 1. 函数类型是 int 和 char 型。 2. 被调函数的定义出现在主调函数前。 3. 在整个文件开头,在函数外部集中做了函数声明。 如: char letter ( ) ; float f ( ) ;int j

17、 ( ) ;main ( ) /*不必声明它所调用的函数*/,说明,8.5 函数的嵌套调用函数的嵌套调用,即在调用一个函数的过程中,又调用另一个函数。 如:,例 8. 用弦截法求方程 f(x)=x3-5x2+16x-80=0 的根,1. 取两个不同点x1,x2,如果f(x1)和f(x2)符号相反,则(x1,x2)区间内必有一个根。如果f(x1)与f(x2)同符号,则应改变x1,x2,直到f(x1)、f(x2)异号为止。注意x1、x2的值不应差太大,以保证(x1,x2)区间内只有一个根。,2. 连接(x1,f(x1)和(x2,f(x2)两点,此线(即弦)交x轴于x。,方法:,3. 若f(x)与f

18、(x1)同符号,则根必在(x,x2)区间内,此时将x作为新的x1。如果f(x)与f(x2)同符号,则表示根在(x1,x)区间内,将x作为新的x2。,4. 重复步骤 (2) 和 (3) , 直到 f(x) 为止, 为一个很小的数, 例如 10-6. 此时认为 f(x)0 。,N-S流程图,实现各部分功能的几个函数:,1. 用函数f(x)代表x的函数:x3-5x2+16x-80。 2. 用函数调用xpoint (x1,x2)来求(x1,f(x1)和(x2,f(x2)的连线与x轴的交点x的坐标。 3. 用函数调用root (x1,x2)来求(x1,x2)区间的那个实根。显然,执行root函数过程中要

19、用到函数xpoint,而执行xpoint函数过程中要用到f函数。,include include float f(float x) /*定义函数,以实现f(x) x3-5x2+16x-80 */ float ;=(-.)*+.)*-.;return(); ,*定义xpoint函数,求出弦与x轴交点 */ float xpoint (float x1,float x2) float ;=(*()-*() ()-();return (); ,/* 定义root函数,求近似根 */ float root(float ,float ) float ,;(1);do xpoint(,);();if(*)

20、 /*()与()同符号 */ ;elsex2; while(fabs()0.0001);return ();,void main() *主函数 */ float 1,2,1,2,;doprintf( 1,2:);scanf(,1,2);1(1);2(2);while (1*2); root(1,1);printf( root of equation is .n,);,8.6 函数的递归调用所谓递归调用即在调用一个函数的过程中又出现直接或间接地调用该函数本身。 一、直接调用f( ) 函数 调用f( )函数 如: int f ( int x ) int y , z ;z = f (y) ; ret

21、urn ( 2 * z) ;,二、 间接调用f1( ) f2( )调用f2( ) 调用f1( )如: int f1( int x ) int f2 ( int t ) int y , z ; int a , c ; z = f2(y) ; c = f1(a) ; return ( 2*z ) ; return ( 3 + c ) ; ,【例8.7】有5个人,第5个人说他比第4个人大2岁,第4个人说他对第3个人大2岁,第3个人说他对第2个人大2岁,第2个人说他比第1个人大2岁,第1个人说他10岁。求第5个人多少岁,通过分析,设计递归函数如下:10 (n=1)age(n)= age(n-1)+2

22、(n1),age(int n) int c;if (n=1) c=10;else c=age(n-1)+2;return c; main() clrscr( );printf(“%d“,age(5); ,程序如下:,请看看单步运行的情况,age(5)c=age(4)+2;return c;,age(int n) int c;if (n=1) c=10;else c=age(n-1)+2;return c; ,递归过程 跟踪分析: P172图8.11 P173图8.12,age(4)c=age(3)+2;return c;,age(3)c=age(2)+2;return c;,age(2)c=a

23、ge(1)+2;return c;,age(1)c=10return c;,c=10,c=12,c=14,c=16,c=18,例8.8(自学) 求整数n的阶乘n!分析比较:,实际上,递归程序分两个阶段执行回推(调用):欲求n! 先求 (n-1)! (n-2)! 1! 若1!已知,回推结束。递推(回代):知道1!2!可求出3! n!,例 8.8 求整数n的阶乘n!,#include main() int n, i;long result=1;printf(“Input n:“);scanf(“%d“, ,递推法,long fact(long n) long result;if (n 0) ret

24、urn 1; else if (n=0 | n=1) /*递归终止条件*/ return 1; elsereturn (n * fact(n-1);/*递归调用*/ ,例 8.8求整数n的阶乘n!,递归法,#include long fact(long n); main() int n;long result;printf(“Input n: “);scanf(“%d“, ,例 8.8求整数n的阶乘n!,递归法,递归调用过程,执行过程:fact(5)=5*fact(4)fact(4)=4*fact(3) fact(3)=3*fact(2) fact(2)=2*fact(1) fact(1)=1

25、,main,fact(5),fact(4),fact(3),fact(2),fact(1),递归函数,递归方法的基本原理 将复杂问题逐步化简,最终转化为一个最简单的问题 最简单问题的解决,就意味着整个问题的解决 递归调用应该能够在有限次数内终止递归 递归调用如果不加以限制,将无数次的循环调用 必须在函数内部加控制语句,只有当满足一定条件时,递归终止 有时将其称为条件递归,递归函数,任何一个递归调用程序必须包括两部分 递归循环继续的过程 递归调用结束的过程if (递归终止条件成立) return 递归公式的初值; elsereturn 递归函数调用返回的结果值;,例8.9(自学) 汉诺塔问题,“

26、汉诺塔”(Hanoi) 这是一个必须用递归方法才能解决的问题n=64时, 18,446,744,073,709,551,615次 1844亿亿次 每次1微秒,需要60万年,递归问题的提出,AC,AB,CB, AC,BA,BC,AC,A,B,C,n=3,递归问题的提出,AC,AB,CB, AC,BA,BC,AC,A,B,C,递归问题的提出,AC,AB,CB, AC,BA,BC,AC,A,B,C,递归问题的提出,AC,AB,CB, AC,BA,BC,AC,A,B,C,递归问题的提出,AC,AB,CB, AC,BA,BC,AC,A,B,C,n更大些 怎么办?,递归问题的提出,第一步:将问题简化。 假

27、设A杆上只有2个圆盘,即汉诺塔有2层,n2。,A,B,C,递归问题的提出,对于一个有 n(n1)个圆盘的汉诺塔,将n个圆盘分为两部分:上面的 n-1 个圆盘和最下面的n号圆盘。将“上面的n-1个圆盘”看成一个整体。 将 n-1个盘子从一根木桩移到另一根木桩上 将1个盘子从一根木桩移到另一根木桩上,A,C,B,递归问题的提出,将 n个盘子从一根木桩移到另一根木桩上 问题分解为: 将 n-1个盘子从一根木桩上移到另一根木桩上 将1个盘子从一根木桩移到另一根木桩上 设计一个函数,入口参数为n : 将 n个盘子从一根木桩移到另一根木桩上 将 n-1个盘子从一根木桩上移到另一根木桩上 也要调用这个函数来

28、实现 出现了函数调用自己的问题递归调用(Recursive Call),程序如下: #include void main() void hanoi(int n,char one,char two,char three); /* 对hanoi函数的声明 */int m;printf(“input the number of diskes:“);scanf(“%d”,void hanoi(int n,char one,char two,char three) /* 定义hanoi函数,将个盘从one座借助two座,移到three座 */void move(char x,char y); /* 对m

29、ove函数的声明 */if(n= =1) move(one,three);else hanoi(n-1,one,three,two);move(one,three);hanoi(n-1,two,one,three); void move(char x,char y) /* 定义move函数 */printf(“%c%cn“,x,y);,实例 1,实例2 large(),实例2 main( ),8.7 数组作为函数参数C语言中,函数参数可以是常量,变量(包括指针变量),数组名,数组元素,表达式等。数组元素可以作实参,数组名可以作实参和形参。 一、 数组元素作函数实参数组元素作函数实参与变量作实参

30、一样,仍按“值传递”。,数组元素作函数实参 int sum( int x, int y) return (x + y); main( ) int a2=2, 3, s;s = sum( a0, a1 );printf (“ sum = %d”, s); ,示例,数组元素作函数实参(main函数) main ( ) int a10 , b10, i, n=0,m=0, k=0 ;for (i = 0; i 10; i+)scanf ( “ %d ”, .,示例,数组元素作函数实参large ( int x , int y ) int flag ;if ( x y ) flag = 1 ;else

31、 if (x y) flag = 1 ;else flag = 0 ;return ( flag ) ; ,示例,二、 数组名作函数参数数组名代表数组的首地址,它可以作实参和形参。传递数组的首地址,使实参数组和形参数组共用同一段内存单元,其效果是传递整个实参数组。要求:实参和形参都应为数组名。如: int a10= 2, 4, 6, 8, 9, 7, 3, 22, 5, 1 ; int b10;,2 4 6 8 9 7 3 22 5 1,实参数组 a,形参数组 b,说明:1. 数组名作函数参数其实质是 “地址传递” ,若形参数组中各元素的值发生变化,将使实参数组各元素的值也随之而变化。2. 用

32、数组名作函数参数,应在主调函数与被调函数中分别定义数组,且二者的类型应匹配。,传递数组元素个数,另设一参数来接收实参数组元素的个数,被调函数示例,主调函数示例,实例,3. 形参数组也可以不指定大小,常在被调函数中 , 主调函数,数组作函数形参float average ( float array10 ) int i ; float aver , sum=array0 ;for ( i = 1 ; i 10 ; i + + )sum = sum + arrayi ;aver = sum /10 ;return ( aver ) ; ,实例,数组名作函数实参 main ( ) flaot scor

33、e10 , aver ; int i;printf(“input 10 scores :n”);for(i = 0 ; i 10 ; i+) scanf(“%f”, ,实例,数组作函数形式参数 另设一参数来接收数组元素的个数float average ( float array , int n ) int i ;float aver ;float sum = array0 ;for ( i = 1 ; i n ; i + + )sum = sum + arrayi ;aver = sum /n ;return ( aver ) ;,示例,数组名作函数实际参数 并传递数组元素的个数 main (

34、 ) float score_15= 98.5,97,91.5,60,55 ;float score_210=67.5,89.5,99,69.5,77, 89.5 , 76.5 , 54 , 60 , 99.5 ;printf (“the average of A is%6.2fn”,average ( score_1 , 5 ) ) ;printf (“the average of B is %6.2fn ”, average ( score_2 , 10 ) ) ; ,示例,数组名函数实参 main( ) int i , a5 = 1, 2 , 3 , 4, 5 ;add ( a ) ;f

35、or ( i = 0 ; i 5 ; i + + ) printf( “%d ” , ai ) ; add( int b5 ) b0+= 2 ; b1+=2 ; b2+=2 ; b3+= 2 ; b4+=2 ; ,示例,例 8.13 (p181) 用选择法排序。void sort (int array , int n ) int i , j , k , t ;for ( i = 0; i n 1; i+ ) k = i ;for ( j = i + 1; j n; j+ )if ( arrayj arrayk ) k = j ;t=arrayk; arrayk=arrayi; arrayi=t

36、; ,找出a0 a9 中最小元素的下标。,思考题:能否对上述例题程序进行以下替换?,for ( i = 0 ; i n 1 ; i+ )for ( j = i + 1 ; j n ; j+ )if ( arrayj arrayi ) t = arrayi ; arrayi = arrayj ; arrayj = t ;,替换,main ( ) int a10 , i ;printf ( “ enter the array n” ) ;for ( i = 0 ; i 10 ; i+ )scanf ( “ %d ”, ,说明,三、用多维数组作函数参数同一维数组名一样,多维数组名也可作函数的实参和形

37、参。其实质仍是 “地址传递”,即将实参数组的起始地址传给形参数组。这样在内存中实参数组和形参数组共占同一段内存单元。,例 8.14 求3 4矩阵中最大的元素。,二维数组名函数实参 max_value ( int array 4 ) int i , j , max ;max = array00 ;for ( i = 0 ; i max ) max=arrayij;return ( max ) ; void main ( ) int a34=1,3,5,7,2,4,6,8,15,17,4,12 ;printf(“max value is %dn”, max_value(a) ; ,说明1. 被调函

38、数中的形参数组定义时可以不指定行的大小。如: int array310; int array 10 ;2. 实参数组可以大于形参数组。此时形参数组只接收实参数组的一部分,而其余部分不起作用。3. 形参数组可以大于实参数组。此时形参数组全部接收实参数组,形参数组的多余部分无意义。,8.8 局部变量和全局变量 一、局部变量 ( 内部变量 )在函数内部或复合语句内部定义的变量。其作 用域( 即变量的有效区间 )是从定义的位置起到函数 体或复合语句结束为止。 float f ( int a ) int b , c ; main ( ) int n , m ; ,a 有效,m , n有效,b, c有效,

39、说明: 1. 主函数中定义的变量也只在主函数中有效。主函数也不能直接使用其它函数中定义的变量。2. 不同的函数中,可以使用相同名字的变量。3. 形参也是局部变量。4. 复合语句中定义的变量,只在复合语句中有效。 如: main ( ) int a , b; int c; c 的有效范围 a , b的有效范围 ,二、全局变量 ( 外部变量 )在函数以外定义的变量叫全局变量。有效范围:从定义变量的位置到本源程序文件结束。 作用:全局变量可为本源程序文件中其它函数共用。 int p = 1 , q = 5 ;float f1( int a ) int b , c ; char c1 , c2 ;ch

40、ar f2( int x , int y ) int j , k ; main ( ) int m , n ; ,p ,q 的 有效范围,c1,c2 的 有效范围,说明: 1.全局变量增加了函数之间数据的联系,例7.15:float max = 0 , min = 0 ;float average ( float array , int n ) int i ;float aver , sum = array0 ;max = min = array0 ;for ( i = 0 ; i max ) max = arrayi ;else if (arrayi min ) min = arrayi ;

41、sum = sum + arrayi ;aver = sum/n ;return ( aver ) ;,main ( ) float ave , score10 ;int i ;for ( i = 0 ; i 10 ; i + + )scanf ( “ %f ” , 如输入: 99 45 78 97 100 67.5 89 92 66 43 输出: max = 100.00min = 43.00average = 77.65,2. 不必要时不使用全局变量,ave score 10 max min,aver array n max min,max min 全局变量,main 函数,average

42、 函数,3. 在定义点之前的函数要引用外部变量时,则应在该函数中用关键字 extern 作说明。 例 8.16int max ( int x , int y ) int z ; z = x y ? x : y ;return ( z ) ;main ( ) extern int a , b ; printf ( “ %d ”, max ( a , b ) ) ;int a = 12 , b = 8 ; 注意:外部变量的定义与外部变量的说明的区别。,4. 在同一个源文件中,如外部变量和局部变量同名,则在局部变量的作用域内,外部变量不起作用。int a = 3 , b = 5 ; max ( in

43、t a, int b) int c ; c = a b ? a : b ;return ( c ) ; main ( ) int a = 8 ; printf(“%d ”, max ( a , b ) ) ; 结果: 8,a , b为局部变量,外部变量定义,局部变量,全局变量,8.9 动态存储变量与静态存储变量 一、 变量的存储类型全局变量 (外部变量 )变量存储类型:反映的是数据在内存中存储的区域。 全局变量位置:静态存储区。 特点: 在程序开始执行时给全局变量分配一定的存储单元,至到程序执行完毕才释放。 局部变量位置:一般存放在动态存储区。 特点: 函数调用开始时,分配动态存储空间,函数结

44、束时,释放空间。即分配和释放都是动态的。,作用范围,值存在 的时间,静态存储区,动态存储区,用户程序区,用户区,局部变量 (内部变量 ),静态存储变量,动态存储变量,变量的两种属性,两种属性C 语言中,每一个变量和函数都具有两种属性。 即: 数据类型和存储类型。存储类型 数据类型 变量名 ;存储类型具体有: 自动型 ( auto ) 静态型 ( static ) 寄存器型 ( register ) 外部型 (extern ),说明,二、局部变量的存储方式1. 函数中的局部变量除特别说明为静态存储类型外,一般由编译系统自动为其动态分配或释放存储单元。这一类变量也叫自动变量。用 auto 来说明。

45、 如:,int f ( int a ) auto int b , c = 3 ; int b , c = 3 ; ,说明: “ auto” 可以省略。,2. 局部静态变量如要函数中局部变量的值在函数调用结束后仍保 留原值,即其占用的内存单元不释放。可用“static” 来说明变量为“局部静态变量”。 关于局部静态变量的几点说明:(1)局部静态变量属于静态存储类别。(2)在编译时就赋值且赋值一次。而自动变量在函数运行时赋初值。每调用一次函数赋值一次。(3) 若在定义局部静态变量时不赋初值,则编译时自动赋初值 0 ,而对自动变量其初值不确定。(4) 局部静态变量在函数内有效,调用结束后仍然存在,但其它函数不能引用它。,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 高等教育 > 大学课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报