1、刘刘 培培 华华2005年3月12005年3月22005年3月3C程序程序源程序文件源程序文件n函数函数1函数函数m 源程序文件源程序文件1函数函数1函数函数n2005年3月4程序运行情况如下:程序运行情况如下:Enter an integer number:2 2*2*2=8程序的执行总是程序的执行总是从从main函数开始函数开始2005年3月5 一个一个C源程序可以由一个或多个源程序文件组源程序可以由一个或多个源程序文件组成。成。C编译系统在对编译系统在对C源程序进行编译时是以文件源程序进行编译时是以文件为单位进行的。为单位进行的。一个一个C源程序文件可以由一个或多个函数组成。源程序文件可
2、以由一个或多个函数组成。所有函数都是独立的。主函数可以调用其它函数,所有函数都是独立的。主函数可以调用其它函数,其它函数可以相互调用。其它函数可以相互调用。在一个在一个C程序中,有且仅有一个主函数程序中,有且仅有一个主函数main。C程序的执行总是从程序的执行总是从main函数开始,调用其它函数函数开始,调用其它函数后最终回到后最终回到main函数,在函数,在main函数中结束整个程函数中结束整个程序的运行。序的运行。2005年3月62005年3月7程序的输出结果如下:程序的输出结果如下:*Welcome to China*2005年3月8函数类型函数类型 函数名函数名(类型名类型名 形式参数
3、形式参数1,)说明语句说明语句 执行语句执行语句 例如:求两个数的最大值。例如:求两个数的最大值。int max(int x,int y)int z;z=x y?x:y;return(z);类型省略时类型省略时默认为默认为int类型类型没有形式参数没有形式参数为为无参函数无参函数 2005年3月9int max(x,y)int x,y;或或int max(int x,y)形参也可以这样定义形参也可以这样定义 2005年3月10函数名(实参表列)函数名(实参表列)在在C语言中,把函数调用也作为一个表达式。语言中,把函数调用也作为一个表达式。因此凡是表达式可以出现的地方都可以出现函数因此凡是表达式
4、可以出现的地方都可以出现函数调用。例如:调用。例如:welcome();if(iabs(a)max)max=iabs(a);m=max(c,max(a,b);函数调用的一般形式:函数调用的一般形式:2005年3月11程序输出结果:程序输出结果:5050思思考:考:两两个个程程序序有有何何不不同同程序输出结果:程序输出结果:50502005年3月12void swap(int x,int y)int z;z=x;x=y;y=z;printf(nx=%d,y=%d,x,y);main()int a=10,b=20;swap(a,b);printf(na=%d,b=%dn,a,b);程序输出结果:程
5、序输出结果:x=20,y=10a=10,b=20形式参数(形参)形式参数(形参)【例例5.4】编一程序,将主函数中的两个变量的值传编一程序,将主函数中的两个变量的值传递给递给swap函数中的两个形参,交换两个形参的值。函数中的两个形参,交换两个形参的值。单向值传递单向值传递2005年3月13 当函数被调用时才给形参分配内存单元。调用结当函数被调用时才给形参分配内存单元。调用结束,所占内存被释放。束,所占内存被释放。实参可以是常量、变量或表达式,但要求它们有实参可以是常量、变量或表达式,但要求它们有确定的值。确定的值。实参与形参类型要一致,字符型与整型可以兼容实参与形参类型要一致,字符型与整型可
6、以兼容。实参与形参的个数必须相等。在函数调用时,实实参与形参的个数必须相等。在函数调用时,实参的值赋给与之相对应的形参。参的值赋给与之相对应的形参。“单向值传递单向值传递”。2005年3月14程序输出结果:程序输出结果:a=9,b=52005年3月15说明:说明:函数的类型函数的类型决定了函数返决定了函数返回值的类型。回值的类型。若省略函数的若省略函数的类型,系统默类型,系统默认其为认其为int型。型。无返回值的无返回值的函数应将其类函数应将其类型定义为型定义为void 2005年3月16如果不一致,系统自动将表达式类型转如果不一致,系统自动将表达式类型转换为函数类型换为函数类型2005年3月
7、17思考:思考:若要得到单精度实型的圆面积,程序应如何修改若要得到单精度实型的圆面积,程序应如何修改程序运行情况如下:程序运行情况如下:2 122005年3月18void swap(int x,int y)main()swap(a,b);2005年3月19第二种形式省略了参数名,此种形式也称为第二种形式省略了参数名,此种形式也称为函数的原型函数的原型。2005年3月20main()void calc(float x,float y,char opr);float a,b;char opr;printf(nInput expression:);scanf(%f%c%f,&a,&opr,&b);c
8、alc(a,b,opr);void calc(float x,float y,char opr)switch(opr)case +:printf(%5.2f%c%5.2f=%6.2fn,x,opr,y,x+y);return;case -:printf(%5.2f%c%5.2f=%6.2fn,x,opr,y,x-y);return;case *:printf(%5.2f%c%5.2f=%6.2fn,x,opr,y,x*y);return;case /:printf(%5.2f%c%5.2f=%6.2fn,x,opr,y,x/y);return;default:printf(Operator e
9、rr!n);对被调函对被调函数的声明数的声明2005年3月21main()int a5,i,m;for(i=0;i5;i+)scanf(%d,&ai);m=a0;for(i=1;i5;i+)m=min(m,ai);printf(%dn,m);【例例5.11】求求5个数中的最小值。个数中的最小值。int min(int x,int y)return(x0)n2005年3月33程序运行情况如下:程序运行情况如下:2,10 10242005年3月345.5.2 局部变量及其作用域局部变量及其作用域变量的作用域变量的作用域:变量在程序中可以被使用的范围。:变量在程序中可以被使用的范围。根据变量的作用域
10、可以将变量分为根据变量的作用域可以将变量分为局部变量和全局局部变量和全局变量。变量。局部变量(局部变量():在:在函数内函数内或或复合语句内复合语句内定定义的变量以及义的变量以及。作用域作用域:函数内或复合语句内。:函数内或复合语句内。【例例5.19】分析下面程序的运行结果及变量的作用域。分析下面程序的运行结果及变量的作用域。2005年3月35main()int a=1,b=1,c=1;printf(main:ta=%d b=%d c=%dn,a,b,c);sub(a,b);printf(main:ta=%d b=%d c=%dn,a,b,c);int a=2,b=2;printf(comp:
11、ta=%d b=%d c=%dn,a,b,c);printf(main:ta=%d b=%d c=%dn,a,b,c);“分程序分程序”或或“程序块程序块”程序输出结果:程序输出结果:main:a=1 b=1 c=1sub:a=2 b=3 c=1main:a=1 b=1 c=1comp:a=2 b=2 c=1main:a=1 b=1 c=12005年3月36全局变量全局变量():在):在函数外部函数外部定义的定义的变量。变量。作用域作用域:。如在其作用域内的函数或分程序中定。如在其作用域内的函数或分程序中定义了同名局部变量,则在局部变量的作用域义了同名局部变量,则在局部变量的作用域内,同名全局
12、变量暂时不起作用。内,同名全局变量暂时不起作用。【例例5.20】全局变量和局部变量的作用域。全局变量和局部变量的作用域。2005年3月37main()int b=6,c=7;f(b,c);printf(%dt%dt%dn,a,b,c);int a=9,b=8;printf(%dt%dt%dn,a,b,c);c=10;printf(%dt%dt%dn,a,b,c);printf(%dt%dt%dn,a,b,c);printf(%dt%dt%dn,a,b,c);程序输出结果:程序输出结果:5 11 -25 6 79 8 79 8 109 8 105 6 10全局变量全局变量2005年3月38变量的
13、生存期变量的生存期:变量在内存中占据存储空间的时间。:变量在内存中占据存储空间的时间。思考思考:1.何时何时为变量分配内存单元为变量分配内存单元?2.将变量分配在内存的什么将变量分配在内存的什么区域?区域?3.变量占据内存的变量占据内存的时间时间(生存期生存期)?程序代码区静态存储区动态存储区存储分配存储分配动态存储变动态存储变量量静态存储变量静态存储变量2005年3月39变变量量的的属属性性2005年3月40autoauto(自动的)(自动的)register(寄存器的)(寄存器的)static(静态的)(静态的)extern(外部的)(外部的)1自动变量(自动变量(auto类别)类别)局部
14、变量可以定义为自动变量。局部变量可以定义为自动变量。main()int x,y;main()auto int x,y;等价等价可省2005年3月412005年3月42全局静态变量(或称外部静态变量)全局静态变量(或称外部静态变量)static int a;main()float x,y;f()static int b=1;全局静态变量全局静态变量不能省2005年3月432005年3月44int c;static int a;main()float;char s;f()static int b=1;全局静态变量全局静态变量外部变量外部变量2005年3月45问题:问题:全局静全局静态变量态变量的作
15、用的作用域可以域可以扩展到扩展到本程序本程序的其它的其它文件吗?文件吗?2005年3月46注意:注意:外部变量声明用关键字外部变量声明用关键字externextern,而外部变量的,而外部变量的定义不能用定义不能用externextern,只能隐式定义。,只能隐式定义。定义外部变量时,系统要给变量分配存储空间,定义外部变量时,系统要给变量分配存储空间,而对外部变量声明时,系统不分配存储空间,而对外部变量声明时,系统不分配存储空间,只是让编译系统知道该变量是一个已经定义过只是让编译系统知道该变量是一个已经定义过的外部变量,与函数声明的作用类似。的外部变量,与函数声明的作用类似。2005年3月47
16、外部变量声明外部变量声明思考:思考:在在f1函数中声明函数中声明c1、c2的作用是什么?如何修改的作用是什么?如何修改程序使所有函数都可以使用程序使所有函数都可以使用外部变量而又不需要声明?外部变量而又不需要声明?2005年3月48file2.c文件中程序如下:文件中程序如下:extern int i;void f2()int i=3;printf(nf2:i=%d,i);void f3()i=3;printf(nf3:i=%d,i);程序输出结果:程序输出结果:f1:i=2 main:i=2f2:i=3 main:i=2f3:i=3 main:i=3声明外部变量声明外部变量定义外部变量定义外
17、部变量2005年3月49【例例5.26】寄存器变量的使用。寄存器变量的使用。main()long int sum=0;register int i;for(i=1;i=1000;i+)sum+=i;printf(sum=%ldn,sum);程序输出结果:程序输出结果:sum=5005002005年3月501 1按照变量的作用域对变量分类按照变量的作用域对变量分类 局部变量局部变量 全局变量全局变量2 2按照变量的生存期对变量分类按照变量的生存期对变量分类 静态存储变量静态存储变量 包括:包括:局部静态变量局部静态变量和和 全局静态变量全局静态变量 动态存储变量动态存储变量 包括:包括:自动变量自动变量2005年3月51 extern int fan(char a,char b)static int func()(与外部变量类似与外部变量类似)。(与外部静态变量类似与外部静态变量类似)。extern可以省略可以省略