C语言第6章函数市公开课金奖市赛课一等奖课件_第1页
C语言第6章函数市公开课金奖市赛课一等奖课件_第2页
C语言第6章函数市公开课金奖市赛课一等奖课件_第3页
C语言第6章函数市公开课金奖市赛课一等奖课件_第4页
C语言第6章函数市公开课金奖市赛课一等奖课件_第5页
已阅读5页,还剩79页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第六章 函 数 10/10/1第1页函数是C语言基本构件,是C程序必不可少基本元素。在前面几章中,已经使用了如printf()、scanf()、getchar()、putchar()等标准C库函数;还有 strlen(string),strcmp(string1,string2)等字符串函数。10/10/2第2页程序员在设计一个复杂应用时,往往也是把整个程序划分为若干个功效较为单一程序模块,然后分别给予实现,最终再把全部程序模块象搭积木一样装配起来。这种在程序设计中分而治之策略,被称为模块化程序设计方法。C语言程序整体由一个或多个函数组成。每个函数都含有各自独立功效和显著界面。6.1 函数概述

2、10/10/3第3页 编写一个简单函数程序一:main() printf(*n);printf( Hello world!n);printf(*n);程序二:#include main()void print_star();void print_text();print_star(); print_text(); print_star(); void print_line() printf(*n);void print_text() printf( Hello world!n);运行结果:*Hello World!*10/10/4第4页若要出现以下结果,应该怎样修改程序?*Hello Worl

3、d!*Hello World!*#Hello World!#Hello World!#10/10/5第5页修改程序一:main() printf(*n);printf( Hello world!n);printf(*n);printf(*n);printf( Hello world!n);printf(*n);程序二:main() print_line();print_text();print_line();print_line();print_text();print_line();print_line()printf(*n);print_text() printf( Hello world

4、!n);*Hello World!*Hello World!*10/10/6第6页修改程序一:main() printf( # n);printf( Hello world!n);printf( # n);printf( # n);printf( Hello world!n);printf( # n);修改程序二:main() print_line();print_text();print_line();print_line();print_text();print_line();print_line()printf( # n);print_text() printf( Hello world

5、!n);#Hello World!#Hello World!#修改程序一:main() printf(*n);printf( Hello world!n);printf(*n);printf(*n);printf( Hello world!n);printf(*n);函数调用函数定义10/10/7第7页说明:(1)函数是按要求格式书写能完成特定功效一段程序。(2)C语言是以源文件为单位进行编译,一个源程序由一个或多个函数组成。(3)不论main函数放在程序任何位置,C语言中程序总是从main函数开始执行,调用其它函数后,最终在main函数中结束。(4)全部函数都是平行,在定义时相互独立,一个函

6、数不属于另一个函数。函数不能够嵌套定义,但能够相互调用,main函数能够调用任何函数,一个函数能够屡次被调用,而其它函数不能调用main函数。 10/10/8第8页库函数是由编译系统提供已设计好函数,用户只需调用而无须去实现它6.1.2库函数用过了哪些库函数?printf() scanf() getchar() 等,包含在 “stdio.h”strlen(str) strcmp(str1,str2) 等,包含在“string.h”pow() sqrt() 等,包含在“math.h”10/10/9第9页使用库函数应注意以下几个问题:1、函数功效;2、函数参数数目和次序,以及每个参数意义及类型;3

7、、函数返回值意义及类型;4、需要使用包含文件。#include #include int main(void)double x = 2.0, y = 3.0; printf(%lf raised to %lf is %lfn, x, y, pow(x, y); 运行结果:2.000000 raised to 3.000000 is 8.000000Press any key to continue10/10/10第10页 int getchar( ); stdio.h标准输入一个字符 int getch( ); conio.h不回显从键盘直接读入一个字符 int putch( int ch )

8、; conio.h向屏幕直接输出一个字符 char *gets( char * ); stdio.h标准输入一行文字 int puts( char * ); stdio.h标准输出一行文字(自动加换行) double sin( double ); math.h正弦函数sin(x) double pow(double x,double y); math.h xy double exp( double x ); math.h ex double log( double x ); double log10( double x ); math.h lnx log10 x void exit( int

9、status ); tdlib.h强制结束程序 惯用库函数10/10/11第11页库函数普通只能提供一些底层服务功效,而用户自定义函数则能针对详细应用实现一些特殊功效。用户自定义函数就是由程序员自己定义和设计函数,需要程序员来编写函数功效实当代码。定义函数时是相互独立,一个函数并不隶属于另一个函数,即函数不能嵌套定义,但能够相互调用,但不能调用main函数。6.2用户自定义函数10/10/12第12页6.2.1函数定义格式1.无参函数定义格式类型说明符 函数名 ()函数体其中,方括号括起来内容是可选项。 2.有参函数定义格式类型说明符 函数名(形式参数申明)函数体 比如:print_line(

10、void) printf( # n); int max ( int x, int y )int z ;z= xy? x: y;return(z);10/10/13第13页3.空函数C语言中能够有“空函数”,它形式为:类型说明符 函数名() 比如:echoline() 6.2.1函数定义格式#include sum() int main() int s=0;s=sum();printf(%d,s); 10/10/14第14页6.2.2形式参数和实际参数在定义函数时函数名后面圆括号内变量名称为“形式参数”(简称“形参”),把它作被调函数使用时,用于接收主调函数传来数据。在调用函数时,主调函数函数调

11、用语句函数名后面圆括号中参数称为“实际参数”(简称“实参”)。实际参数能够是常量、变量或表示式。 10/10/15第15页#include main() int x,y,z;printf(“Please enter two integer numbers:”);scanf(%d,%d,&x,&y);z=min(x,y);/函数调用printf(min is %dn,z); int min(int a,int b) /函数定义 int c;c=ab?a:b;return (c); 6.2.2形式参数和实际参数函数形参a,b函数实参x,y实参x和y值按次序对应传递给被调函数min(a,b)中形参a

12、和b,x传给a,y传给b。在执行被调函数min后,其返回值c作为函数返回值返回给主调函数,作为min(x,y)值,赋给变量z。 10/10/16第16页例6-3 编写函数求两个实数平均值。 #include float average(float x,float y)float av;av=(x+y)/2.0;return av; main()float a=1.8,b=2.6,c;c=average(a,b);/第一次调用函数average()a=1.0;b=2.0;printf(The avergae of %5.2f and %5.2f is %5.2fn,a,b,average(a,b

13、);/第二次调用函数average()c=average(a,a+b);/第三次调用函数average()printf(The avergae of %5.2f and %5.2f is %5.2fn,a,a+b,c); c=average(2.0,4.0);/第四次调用函数average() printf(The avergae is %5.2fn,c); printf语句中调用,xy接收a,b值形式参数x、y接收实参变量a、b值 表示式a+b作为实参之一 常量作为实参10/10/17第17页关于形参和实参说明以下:(1)函数中指定形参变量,在未出现函数调用时,并不占用内存中单元。在发生函数

14、调用时,被调函数形参被暂时分配内存单元,调用结束后,形参所占内存单元被自动释放。(2)函数一旦被定义,就可屡次调用,但必须确保形参和实参数据类型一致。假如实参为int型而形参为float型,这是正当;假如实参为float型而形参为int型 ,则按不一样类型数值赋值规则进行转换。比如实参a为float型变量,其值为3.5,而形参x为int型,则在传递时先将实数3.5转换成整数3,然后送到形参x。字符型与整型能够相互通用。(3)实参能够是常量、变量或表示式,但要求它们有确定值。在调用时将实参值赋给形参。(4)在被定义函数中,必须指定形参类型。(5)C语言要求,实参对形参变量数据传递是“值传递”,即

15、单向传递,只由实参传给形参,而不能由形参传回给实参。 10/10/18第18页函数执行最终一个操作是返回。返回意义是:(1) 使流程返回主调函数,宣告函数一次执行结束,在调用期间所分配变量单元被撤消。(2) 送函数值到调用表示式中。有些函数有返回值,有些函数没有返回值。return语句使用格式是: return;或者 return (表示式);或者 return 表示式;6.2.3函数返回值10/10/19第19页说明:(1)return语句有双重作用:它使函数从被调函数中退出,返回到调用它代码处,并向调用函数返回一个确定值。(2)一个函数中能够有多个return语句,执行到哪一个return

16、语句,哪一个语句就起作用。(3)在定义函数时应该指定函数值类型,而且函数类型普通应与return语句中表示式类型相一致,当二者不一致时,应以函数类型为准,即函数类型决定返回值类型。对于数值型数据,能够自动进行类型转换。 10/10/20第20页#include int sum(int n)int i,s=0;for(i=0;i=m;i+) s=s+i;return s;int main() int s;s=sum(50);printf(%d,s); 用自定义函数,实现1+2+3+50程序分析:自定义函数int sum(int n);return s;定义变量;int s=0;int i;10/

17、10/21第21页提议函数无返回值时用void标识函数类型,则系统可确保函数不带回任何值,即禁止在调用函数中使用被调用函数返回值。return语句其它规则: return只能返回一个值,而不能返回多个值。假如函数中没有return语句,并不代表函数没有返回值,只能说明函数返回值是一个不确定数。10/10/22第22页void类型函数有时调用一个函数并不是为了得到它返回值,而是要它产生一些作用。这类确实没有返回值函数,我们通常将它定义为空类型(void)函数。 一旦将一个函数定义为空类型函数,那么该函数中return语句仅仅起到结束函数运行功效,它是不返回任何值给主调函数。返回语句只能写成以下形

18、式: return;10/10/23第23页6.3函数调用所谓函数调用,是指一个函数(调用函数)暂时中止本函数运行,转去执行另一个函数(被调函数)过程。被调函数执行完后,返回到调用函数中止处继续调用函数运行,这是一个返回过程。函数一次调用必定伴伴随一个返回过程。在调用和返回两个过程中,两个函数之间发生信息交换。 函数调用普通形式为:函数名(实际参数表列); 调用无参函数,则“实际参数表列”能够没有,但括号不能省略。 实际参数表列中实参类型及个数必须与形参相同,而且次序一致,当有多个实参时,参数之间用逗号隔开。 实参能够是常量,有确定值变量或表示式及函数调用 10/10/24第24页(1) 实参

19、个数、次序与类型要与形参一一对应;(2) 变量作形参时, 对应实参能够是常数, 变量或表示式;(3) 调用函数有两种: 标准函数(库函数)和用户自定义函数。 * 调用标准函数(库函数) , 需在程序前使用包含命令:例:#include ”stdio.h” 或 #include 等 * 调用用户自定义函数, 普通应在调用前“申明”被调用函数“类型”。 函数调用标准 除非1) 被调函数是整型或字符型函数;2) 被调函数定义出现在这个函数调用之前;3) 在文件开头已对被调函数类型作了说明.10/10/25第25页6.3.2函数调用方式按被调用函数在主调函数中出现位置和完成功效划分,函数调用有以下三种

20、方式:(1)把函数调用作为一个语句。如例6-1中“print_star();”,这时不要求函数带回值,只要求函数完成一定操作。(2)在表示式中调用函数,这种表示式称为函数表示式。这时要求函数带回一个确定值以参加表示式运算。比如:c=average(a,b);d=5* average(a,b);(3)将函数调用作为另一个函数调用实参。比如:printf(The avergae of %5.2f and %5.2f is %5.2fn,a,b,average(a,b);此处把average(a,b)作为printf函数一个参数。 10/10/26第26页函数调用普通形式 函数名(实际参数表);其中

21、,实际参数能够是常量或变量,也能够是各种表示式;参数个数和类型应该与函数要求形式参数个数和类型一致;参数间用逗号隔开。假如调用无参函数,则实参表能够没有,但括号不能省略。函数调用普通形式10 #include stdio.h20 main()30 40 void function (int n); 50 function(5); 60 70 void function(int n) 80 90 printf(%dn,n); 100 函数说明函数调用函数定义形参实参10/10/27第27页main( ) int a, b, c, d, max(int x, int y) ;void star(

22、) ;printf(nInput a,b,c = ?n);scanf(%d, %d, %d, &a, &b, &c);d = max(a, max(b,c) ) ;printf(max is %d , d);star(); max(int x,int y) int z;z= xy? x: y;return(z);void star( )printf(n*); abc( ) 被调函数申明自定义函数调用函数定义可写成:int max( x, y)int x, y;C程序执行时从主函数开始,可调用其它函数, 最终返回主函数并结束运行。比如 找出 a,b,c 中最大值.函数应用举例10/10/28第2

23、8页6.3.3函数原型申明函数申明普通形式为:类型说明符 函数名(形参表); 比如:float average(float x,float y);也能够写为:float average(float,float) ; 实际上就是函数定义时函数头,最终加分号组成一条申明语句。与函数头区分是,函数申明中形参表中能够只写类型名,而不写形参名。 10/10/29第29页例6-5编写函数求两个实数平均值。#include main() float a=1.8,b=2.6,c; float average(float x,float y);/函数申明 c=average(a,b); /函数调用 printf

24、(The avergae of %5.2f and %5.2f is %5.2fn,a,b,c);float average(float x,float y)float av;av=(x+y)/2.0;return av; 函数定义10/10/30第30页在以下情况下能够缺省函数申明:(1) 调用是在定义有效区域,即在同一文件中位于定义之后调用。也就是函数定义写在前面,主调函数写在后面。省略函数说明10 float max(float x,float y)20 30 return(xy)?x:y);40 50 main()60 70 float x=5.5,y=9.7,z;80 z=max(x

25、,y);90 printf(The max is %f,z);100 例:10/10/31第31页(2) 返回值为int或char类型。省略函数说明10 main()20 30 int x=5,y=9,z;40 z=max(x,y);50 printf(The max is %d,z);60 70 max(int x, int y)80 90 return(xy)?x:y);100 提议:为了便于阅读和了解,应该养成在调用之前都做显式申明格调。当一个函数要被一个文件中多个函数调用时,能够将该函数申明写在全部函数之前。例:10/10/32第32页在主调函数内部进行说明在调用函数前,能够在主调函数

26、内部对被调函数进行说明。假如使用这种说明方式,则此次函数说明只在主调函数内部有效,也就是说,假如其它函数中也需要调用该被调函数,在那些函数中对被调函数依然需要进行说明。10 #include 20 main( )30 40 int x=1;50 void f1( ), f2( );60 f1( );70 f2(x); 80 printf(%dn, x);90 100 void f1(void)110 120 void f2();130 int x=3; 140 f2(x);150 printf(%d , x);160 f2(x);170 180 void f2(int x )190 200 p

27、rintf(%d , +x); 210 例:函数说明函数说明10/10/33第33页在主调函数外部进行说明#include 20void f1( ), f2( ); 30 main( )40 50 int x=1;60 f1( );70 f2(x); 80 printf(%dn, x);90 100 void f1(void)110 120 int x=3; 130 f2(x);140 printf(%d , x);150 f2(x);160 170 void f2(int x )180 190 printf(%d , +x); 200 例:函数说明假如已经在文件开头(或在函数前)对某函数进行

28、了说明,则从说明处开始,在本文件中对说明函数调用不需要再次进行说明。比如:10/10/34第34页6.3.4函数参数传递在C语言中进行函数调用时,有两种不一样参数传递方式,即值传递方式和地址传递方式。 1.值传递在函数调用时,实参将其值传递给形参,这种传递方式即为值传递。 C语言要求,实参对形参数据传递是“值传递”,即单向传递,只能由实参传递给形参,而不能由形参传回来给实参。 所以,在执行一个被调用函数时,形参值假如发生改变,并不会改变调用函数中实参值。 10/10/35第35页10 #include stdio.h20 float average(float x, float y, floa

29、t av)30 40 av = (x+y)/2.0;50 printf(function:x=%f, y=%f, av=%fn, x, y, av);60 return av;70 80 main()90 100 float a=1.4, b=2.6, c=3;110 average(a,b,c);120 printf(main:a=%f, b=%f, c=%fn, a, b, c);130 单向传递程序运行结果是:function:x=1.400000, y=2.600000, av=2.000000main:a=1.400000, b=2.600000, c=3.00000010/10/3

30、6第36页运行位置main函数变量average函数变量说明abCxyav1001.42.63不存在不存在不存在程序开始运行1101.42.631.42.63分配形参存放空间,实参向形参传递数值601.42.631.42.62运算1201.42.63不存在不存在不存在函数调用结束,返回主调函数程序运行过程和参数传递情况 单向传递10/10/37第37页实参向形参传递数值过程: 单向传递一次实参向形参传递数值过程,只是在发生函数调用时候执行一次。假如实参是表示式或函数形式,那么一定要先完成表示式运算,将该运算结果传递给形参。单向只能是实参把数值传递给形参,而形参是不可能把数值传递给实参。10/1

31、0/38第38页单向传递int swamp(int i,int j)int t;t=i;i=j;j=t;printf(In function i=%d,j=%dn,i,j);main()int i=2,j=3;swamp(i,j);printf(Out function i=%d,j=%d,i,j);程序运行结果是:In function i=3,j=2Out function i=2,j=3读程序写结果10/10/39第39页float abc(float x, float y) float av ; x=x*x; y=y*y; av = (x+y)/2.0 ; printf(“nfunct

32、ion x=%3.2f y=%3.2f av=%-5.2fn, x, y, av); return (av); 变量作参数 单向传递实参 形参已知 x,y计算 av=? #include main() float a=1, b=2, c ; c=abc(a, b); printf(“main a=%3.2f b=%3.2f c=%3.2fn , a, b, c );运行结果:function x=1.00 y=4.00 av=2.50main a=1.00 b=2.00 c=2.50传值调用举例10/10/40第40页float abc(int a, int b) float av; a=3*

33、a; b=4*b; av = (a+b)/2.0 ; printf(“nfunction a=%2d b=%d av= %-5.2fn, a, b, av); return(av);main()int a=1, b=2 , c;c = abc( a, b ); printf(main a=%2d b=%2d c=%-8dn, a, b, c );* 数据只能由实参传给形参;* 使用 return 返回一个计算结果;* 返回值类型要与函数值一致。* 实参个数、次序与类型要与 形参一一对应,如 形参 a, b 与 实参 a, b function x=3 y=8 av=5.50main a=1 b

34、=2 c=5传值调用举例10/10/41第41页2.地址传递地址传递指是调用函数时,实参将一些量(如变量、字符串、数组等)地址传递给形参。这么实参和形参指向同一个内存空间,在执行被调用函数过程中,对形参所指向空间中内容改变,能够直接影响到调用函数中对应量。在地址传递方式下,形参和实参能够是指针变量(见第8章)或数组名,其中,实参还能够是变量地址。 10/10/42第42页例:int max(int a1, int a2, int a3);max(int a1, int a2, int a3);char GetName(char surname, char name);GetName(char

35、surname, char name);例:double func(x, y, z);func(double x, int y, float z);double func(int y, float z, double x);没有说明形参类型。没有说明函数类型。形参次序错误。例(函数说明):double func(double x, int y, float z);double func(double, int, float);正确完整函数模型定义。形参名字是不主要,主要是类型标识符。函数说明能够不写形参名函数返回值为int或char时,函数类型标识符才能够省略。当然,申明也可省略判断以下对函数

36、定义是否正确1、定义一个返回值为double类型函数,并有三个参数,参数类型分别为double,int,float型。2、定义一个返回值为int或char类型函数。10/10/43第43页例:int func3() int i, j, k; i = 2; j = i*i; k = j*j;printf(“%d,%d,%d”, j, j, k); 非空类型函数,必须在函数返回前使用return语句返回一个数据类型与函数类型相同值。 在本例中,应该返回一个整型值。例:float func2(float a, float b) float a, b, c; c = a+b; return c;形参变

37、量数据类型已经在形参表中说明,在函数体中不应该对形参变量数据类型再行说明。例:void func1(a, b, c) printf(“%d,%d,%dn”, a, b, c); 函数形式参数表中形参变量数据类型应该被说明。正确形式:void func1(int a, int b, int c) printf(“%d,%d,%dn”, a, b, c); 10/10/44第44页6.4函数嵌套调用和递归调用C语言中函数定义是相互平行,在定义函数时,一个函数不能包含另一个函数,不过,一个函数在被调用过程中能够调用其它函数,这就是函数嵌套调用。 6.4.1函数嵌套调用10/10/45第45页计算 s

38、 = 1!+2!+3!+ + 150! = ? 设计1: 一个主函数,嵌套循环#define N 150 /* =170 */main() int i, j;long float t, s=0;for (i=1; i= N; +i)t= 1;for (j=1; j=i; +j) t *= j ;s += t;printf(s= %-12.5 len, s); 函数嵌套调用举例10/10/46第46页设计2: 一个主函数和两个子函数, 嵌套调用#define N 150main() long float sum() ;printf(ns=%-12.5le, sum(N) );long float

39、 sum(int n) long float fa() , s=0;int i;for (i=1; i=n; +i) s=s+ fa(i) ;return s;long float fa(int k) int i; long float t;t= 1;for (i=1; i=k; +i) t*=i ;return t;注意函数申明 函数嵌套调用举例10/10/47第47页在调用一个函数过程中又直接或间接地调用该函数本身,称为函数递归调用。函数递归调用是C语言主要特点之一。 6.4.2函数递归调用直接递归间接递归10/10/48第48页#include long rfact(int n)if(n

40、0)printf(Negative argument to fact!n);exit(-1); else if(n=1) return(1); else return(n*rfact(n-1);/自己调用自己 main()int n;long f;printf(Please input an integral number:);scanf(%d,&n);f=rfact(n); printf(%d!=%ldn,n,f); 运行结果:Please input an integral number:55!=120 10/10/49第49页4 * rfact(3)3 * rfact(2)2* rfac

41、t(1)1 计算 rfact(4) 2*1(3* 2*1)(4* 3* 2*1)输出 (4* 3* 2*1)回推递推 函数递归调用过程10/10/50第50页数组元素能够作为函数实参,其使用方法与变量相同,是单向传递,即“值传递”方式;但不能作形参!数组名既能够作为实参也可做形参,传递是整个数组。数组名作函数参数时,不是“值传送”,而是把实参数组起始地址传递给形参数组,这么两个数组就共占有同一段内存单元。这种传递方式叫“地址传送”。6.5数组作为函数参数数组作为函数参数有两种形式:数组元素作为函数参数和数组名作为函数参数 10/10/51第51页 数组元素作为函数参数10 #include s

42、tdio.h20 int function(int a)30 40 return a%2; 50 60 main()70 80 int s8=1,3,5,2,4,6,i,d=0;90 for (i=0; function (si);i+)100 d+=si;110 printf(%dn,d);120 程序运行结果:9在采取数值传递方式向形参传递数组元素数值时,只能把需要数组元素数值传递给形参,不允许把数组作为一个整体传递给形参。传值调用10/10/52第52页用数组名作函数参数,应该在主调函数和被调用函数分别定义数组,不能只在一方定义。实参数组与形参数组类型应一致。 数组名作为函数参数10 f

43、loat average();20 main()30 40 float avg;50 float x10=1.2,3.6,4.5,5.1,6.9,7,8,9,10.5,11.3;60 avg=average(x);70 printf(The average is %5.2f,avg);80 90 float average(float a10)100 110 int i;float sum=0;120 for (i=0;i10;i+)130 sum=sum+ai;140 return (sum/10);150 传址调用10/10/53第53页main()void swap(int x2);in

44、t a2 = 4, 9;printf(“%d, %dn”, a0, a1);swap(a);printf(“%d, %dn”, a0, a1);void swap(int x2)int t;t = x0;x0 = x1;x1 = t;运行4,99,4思索:若不用数组,用两个变量名来做是否能够? 数组名作为函数参数举例10/10/54第54页int swap(int i,int j)int t;t=i;i=j;j=t;printf(In function i=%d,j=%dn,i,j);main()int i=4,j=9;swap(i,j);printf(Out function i=%d,j=

45、%d,i,j);main()void swap(int x2);int a2 = 4, 9;printf(“%d, %dn”, a0, a1);swap(a);printf(“%d, %dn”, a0, a1);void swap(int x2)int t;t = x0;x0 = x1;x1 = t;比较两程序输出结果,说明结果不相同原因传值调用数组名作为函数参数,传址调用10/10/55第55页 数组名作为函数参数举例有一个数组score,内放10个学生成绩,求平均成绩。#include float average(float array )int i; float aver,sum=0;

46、for(i=0;i10;i+) sum=sum+arrayi; aver=sum/10; return(aver); main()float score10,aver;int i; printf(input 10 scores:n);for(i=0;i10;i+)scanf(%f,&scorei);aver=average(score);printf(average score is %5.2f,aver); 运行结果:input 10 scores:45 100 90 89 78 67 75 55 86 98average score is 78.30 10/10/56第56页输入10个学生

47、成绩,求平均成绩,并将低于平均成绩分数打印出来。要求:1、用数组fScore存放10个学生成绩。2、分别编写三个函数:readdata, aver和print,用来输入学生成绩,求平均分和打印低于平均成绩分数。10/10/57第57页在一个函数内部定义变量是内部变量(局部变量),它作用范围是从定义处开始到本函数结束为止. 注意:1、在主函数main中定义变量只在主函数中有效。主函数也不能使用其它函数中定义变量。2、不一样函数中能够使用名字相同变量。3、形参是局部变量。4、在复合语句中定义变量是局部变量,它们只在本复合语句中有效,离开该复合语句就无效。6.6 局部变量和全局变量 局部变量10/1

48、0/58第58页 局部变量#include main()int x=10; int x=20; printf(%d,,x); printf(%dn,x); 分析以下程序运行结果。运行结果:20,10 输出复合语句中x,20输出main函数中x,1010/10/59第59页在函数之外定义变量称为外部变量,外部变量是全局变量。全局变量可认为本文件中其它函数所共有。它有效范围:从定义变量位置开始到根源程序文件结束。在一个函数中既可以使用本函数中局部变量,又可以使用有效全局变量。 注意:1、全局变量作用:增加了函数间数据联络渠道。2、在同一个源文件中,全局变量与局部变量同名,则在局部变量作用范围内,全

49、局变量不起作用。 全局变量10/10/60第60页传值调用,主函数中a值未发生改变10 int d=1;20 fun(int p)30 40 int d=5;50 d+=p+;60 printf(%d,d);70 80 main()90 100 int a=3;110 fun(a);120 d+=a+;130 printf(d=%d,a=%dn,d,a); 140 程序运行结果:d=8,p=4d=4,a=4 全局变量局部变量局部变量d为全局变量a为局部变量10/10/61第61页1.全局变量提供了另外函数间进行数据联络渠道,这种方式有效地处理了函数只能经过return语句带给主调函数一个运算结

50、果情况。 2. 经过全局变量在不一样函数间传递数据,能够有效地降低形参个数,使函数书写愈加简练。3.因为全局变量在开始运行程序时就已经分配了存放空间,而且在程序运行过程中并不释放这些存放单元,所以经过全局变量传递数据时在函数调用过程中没有分配和释放形参存放单元过程,能够降低参数传递是时间开销。 使用全局变量好处10/10/62第62页 使用全局变量弊端内存开销大和局部变量“用之则建,用完即撤”方式不一样,全局变量从程序开始运行时候就占据了内存单元,直到程序运行结束才会释放这些存放空间。通用性差全局变量使用使不一样函数之间“耦合性”增强,每个函数“独立性”降低。可读性差在不一样函数中碰到全局变量

51、时难以判断当前该变量取值,因为各个函数执行时都可能改变全局变量数值,这给程序调试带来麻烦。 提议:编程时尽可能不用全局变量10/10/63第63页6.7 变量存放类别变量存放期是该变量在内存中存在期。一些变量存在是短暂,有些变量会被重复地建立和撤消,而另外一些变量存在于程序整个执行期间。依据变量存在期不一样,能够将变量存放方式分为静态存放方式和动态存放方式。C语言中能够用以下4个关键字来表示存放类别:auto(自动)static(静态)register(存放器)extern(外部)10/10/64第64页 存放期属性用户区存放auto变量、 register变量、 函数返回值、被调用函数形参、

52、保留调用现场数据。存放 static变量、 extern变量存放执行程序代码 程序区 静态存放区 动态存放区 C语言程序运行时所用存放空间,普通包含三部分:程序运行过程中使用变量分别存放在静态存放区和动态存放区中。10/10/65第65页 存放期属性静态存放区中存放了在整个程序执行过程中都存在变量,比如全局变量。这类变量在程序开始运行时就取得了存放空间,直到程序运行结束才释放存放空间,在程序运行过程中,这类变量都占有固定存放单元,而不是动态地进行分配和释放。动态存放区中存放变量是依据程序运行需要而建立和释放。通常情况下,存放在动态存放区中变量包含:函数形式参数、返回值;自动变量、存放器变量;函

53、数调用时现场保护和返回地址等。10/10/66第66页自动变量是C程序中使用最多一个变量。因为建立和撤消这些变量,都是由系统自动进行,所以称自动变量。自动变量在使用之前先按以下形式进行说明: auto 数据类型 变量名 = 初始表示式,.;auto是自动变量存放类别标识符。可省略。自动变量是局部变量未进行初始化时,自动变量值是不定。函数形参也是一个自动变量,不过在说明时不加存放类型标识符“auto”。对同一函数两次调用之间,自动变量值是不保留。因为其所在存放单元已被释放了。 自动变量10/10/67第67页 局部静态变量假如希望在函数调用结束后依然保留其中定义局部变量值,则能够将局部变量定义为

54、局部静态变量。申明局部静态变量普通形式为:static 类型说明符 变量名 说明:(1)局部静态变量是在静态存放区分配存放单元。一个变量被申明为静态,在编译时即分配存放空间,在整个程序运行期间都不释放。所以,函数调用结束后,它值并不消失,其值能够保持连续性。(2)局部静态变量是在编译过程中赋初值,且只赋一次初值,在程序运行时其初值已定,以后每次调用函数时,都不再赋初值,而是保留上一次函数调用结束时结果。(3)局部静态变量在未显式初始化时,编译系统把它们初始化为0(整型变量)、0.0(实型变量)或空字符(字符型变量)。 10/10/68第68页#include main()int i,j=2;f

55、or(i=0;i3;i+)printf(%4d,function(j);printf(n);函数调用开始时函数调用结束时bcbc第一次调用0011第二次调用0112第三次调用0213int function(int a)int b=0; static int c; b+; c+;return (a+b+c); 运行结果为: 4 5 6 10/10/69第69页10 main()20 30 int j=2,i;40 for(i=0;i3;i+)50 printf(%4d, function (j);60 70 function(int a)80 90 int b=0;100 static int

56、 c=3;110 b+;120 c+;130 return(a+b+c);140 例 读程序, 写出程序运行结果。程序运行结果: 7 8 9静态变量,存放空间不释放静态变量若未赋初值,则默认初值为0见例6-2510/10/70第70页#includemain() int k4;m1,p; pfunc(k,m); printf(“%d”,p); pfunc(k,m); printf(“%dn”,p);func(int a,int b) static int m,i2; i+m+1; mi+a+b; return(m);自动类型变量静态类型变量,默认初值为0程序运行结果: 817i 2+1=3 m

57、 3+1+4=8i 3+8+1=12 m 12+1+4=1710/10/71第71页存放器变量含有与自动变量完全相同性质。当把一个变量指定为存放器存放类别时,系统就将它存放在CPU中一个存放器中。通常把使用频率较高变量(如循环次数较多循环变量)定义为register类别。 存放器变量(1)只有局部自动变量和形参能够作为存放器变量,其它(如全局变量、局部静态变量)则不行。 (2)只有int、char和指针类型变量可定义为存放器型 (3)可用于变量空间分配存放器个数依赖于详细机器。 10/10/72第72页#include void m_table(void)register int i,j;/定

58、义存放器变量for(i=1;i=9;i+)for(j=1;j=i;j+)printf(%d*%d=%d ,j,i,j*i);printf(n); 存放器变量应用 main()void m_table(void);m_table(); 因为频繁使用变量i、j,故将它们放在存放器中。 10/10/73第73页在多个源程序文件情况下,假如在一个文件中要引用其它文件中定义全局变量,则应该在需要引用此变量文件中,用extern进行说明。在一个文件中,定义在函数之外变量称为外部变量。外部变量作用域是“全程”(全局),即从定义位置开始到本文件结束。假如在一个函数中改变了外部变量值,那么其后引用该变量时,得到是已被改变值。外部变量也能够不出现在文件开头,而出现在两个函数之间。 外部全局变量6.7.2全局变量存放类别10/10/74第74页#include 10

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论