1、第8章 函数 8.1 概述 一个C程序,由一个主函数和若干其它函数组成,它们之间的关系是: 主函数可以调用其它函数,其它函数可相互调用。且一个函数可以被调用若干次 注:每个函数都是独立的,平等的! 函数:完成特定功能的程序段,通常由用户定义或系统定义 各函数可存放在一个文件中,也可以存放在不同的文件中。,某程序整体结构,,程序运行轨迹: maina d a e a main b f e f b g b h b main c h g h c i c main,举例:用常规、文件包含两种方法打印字符串 一、常规方法:各函数包含在一个文件中 例T8-1.c main( ) p1( );p2( );p
2、1( ); p1( ) printf (“* n” ); p2( ) printf (“_ _ _ _ _How_do_you_do!n”) ;,运行结果: *_ _ _ _ _How_do_you_do! _ _ _ _* *,二、文件包含的方法 在主函数所在的文件中使用文件包含预编译命令,将不在本文件而在其它文件中的函数进行预编译处理,把各文件中的函数包含到本文件中来,然后一起进行编译、连接、运行。 T8-1-3.c #include “T8-1-1.c” #include “T8-1-2.c” main( ) p1( ); p2( ) ; p1( ) ; 运行结果同上 友情提示:还可以用
3、项目的方法,T8-1-1.c p1( ) printf (“* n”); ,T8-1-2.c p2( ) printf (“_ _ _ _ How_do_you_do! n”); ,说明: (1)一个文件可含多个函数,编译的单位是文件而不是函数; (2)一个完整的程序可由若干个文件组成,可用项目或文件包含的方法对其编译; (3)C执行总是从main函数开始执行,调用其它函数后又返回到main函数; (4)函数定义是独立的、平等的,不能嵌套定义(即函数里不能再定义函数)但可相互调用; (5)函数的类型: 标准库函数,由系统提供,用户直接使用用户定义的函数 (6) 函数的形式: 无参函数 主调函数
4、无数据传给被调函数,可带或不带返回值.有参函数 主调函数与被调函数间有参数传递,主调函数可将实际参数传送给被调函数的形式参数,被调函数的函数值可传回主调函数。,8.2 函数定义的一般形式 1.无参函数的定义形式: 类型标识符 函数名( ) 声明部分语句部分注:无参函数一般不返回函数值,故类型标识符可省。 2.有参函数的定义形式: 类型标识符 函数名(形式参数表列) 声明部分语句部分,其中: 类型标识符:指出函数返回值的数据类型 (int, float,char等),系统默认为int函数名:合法的标识符;形参表列:接收主调函数传递过来的实参,其中包括对形参类型的声明(老版本中形参类型进一步声明放
5、在下一行)。形参类型:与实参类型要一致。 :称函数体,包括声明部分:定义局部变量的数据类型;语句部分:完成函数功能的若干执行语句。,例: int max(int x,int y) int z;z= xy ? x : y ; return(z) ; ,3.空函数的定义形式 类型说明符 函数名( ) 例: p1( ) 空函数不作任何操作,但是合法,它对调试程序或以后在此处补充完整的函数体是 有作用的。,4.对形参声明的传统方式 传统方式中,形参类型说明在函数定义的第2行 如:传统形参声明形式 int max(x,y) int x,y; int z; z=xy ?x:y; return(z); ,新
6、版本形参声明形式 int max(int x,int y) int z; z=xy ?x:y; return(z); ,以上两种定义形式在Turbo C中都认可,8.3 函数参数和函数的值 8.3.1 形式参数和实际参数 实际参数:主调函数中提供的数据。可以是常量、变量、表达式等,是具体的数值。 形式参数:被调函数中用以接收主调函数数据的变量。被调用函数名后面括号内的若干变量名。,例T8-2.c 调用函数时的数据传递 main( ) int a, b, c;scanf(%d%d”, ,输入:-100 200Max is 200,关于形、实参的说明: 1.形参只有在函数调用时才分配存储单元,调用
7、结束后,释放所分配的单元; 2.实参可以是常量、变量、表达式:max(3,a+b),总之要有确定的值,当函数调用时,将实参的值传递给形参,若是数组名,则传送的是数组的首地址。 3.被调函数中,形参类型必须指定,以便分配存储单元。,4.实参、形参的数据类型一致,赋值要兼容,顺序要一致。如果形、实参类型不一致时,则按赋值规则进行。通常被调函数放在主调函数之前,以便编译系统对函数类型和形参类型作合法性检查。若被调函数在主调函数之后,一般要对被调函数作原型声明。 main() float a=4.5,b=4.5; int abc(int,int); abc(a,b); abc(int x,int y)
8、 printf(“x=%d,y=%dn”,x,y); 结果:x=4,y=4,5.若被调函数类型为非整形或实参形参类型不匹配,要在主调函数中对被调函数作原形声明。另外若被调函数在主调函数之前定义,则原形声明可省,因为编译系统已经知道被调函数的类型及其形参的个数、类型了。 6.实参对形参的数据传送是值传送,也是单向传送,当被调函数的形参发生变化时,并不改变主调函数实参的值。,例T8-2-1.c 形、实参占据的是不同的存储单元 main( ) int a=2,b=3; printf (“a=%d, b=%d n”,a, b); printf(“ ,运行结果: a=2,b=3 &a=ffd6,&b=f
9、fd8 x=10,y=15 &x=ffd2,&y=ffd4 a=2, b=3 &a=ffd6,&b=ffd8,8.3.2 函数的返回值 调用一个函数一般都希望返回一个确定的值。 有关函数值的几点说明: 1.若需要返回值则用return语句; 2.被调函数中可用多个return语句,执行哪一个由程序执行情况来定。 例:函数中有如下语句if(ab) return(a);else return(b); 3.return后面的括号可省,如:return a;,4.return 后的值可以是一个表达式,如:return(x y ? x : y); 5.函数值的类型是在定义函数时指定的如: int max
10、(x, y)float min(a,b)double abc(d1,d2) 6.语句return(a,b,c)是合法的,返回表达式c的值。 注意: (1)函数定义时,函数名的括号后无 “ ;” ;(2) 未加类型说明的函数自动按整型处理;(3) 定义函数时,函数值的类型一般与return 后面表达式的类型一致,若不一致, 则以函数值为准。,例T8-3.c 函数值类型为整型,而返回值的类型是实型,最后以整型值返回。即以函数类型为准 main( ) int max(float,float);/*原型声明*/ float a, b; int c;scanf(“%f%f”,输入: 1. 5 2. 5
11、输出:max is 2,6.函数中无return 语句时,可能返回一个不确定或无用的值例T8-3-1.cmain( )int a, b, c; a=p1( ); b=p2( ); c=p1( ); printf(“a=%d,b=%d,c=%d n”,a, b, c); p1( ) printf(“* n”); p2( ) printf(“ I am happy! n”); ,运行结果: * I am happy! *a=6,b=12,c=6,7.为明确表示不带返回值,可用void(无值,空类型)定义函数。 例T8-3-2.c main( ) int a,b,c; a=p1( ); b=p2(
12、); c=p1( ); printf(“a=%d, b=%d, c=%d n”,a, b, c); void p1( ) printf(“* n”); void p2( ) printf(“I am happy! n”); ,编译时指出: Type mismatch in redeclartion of p1 , p2 意即:在定义函数 p1, p2 时类型不匹配,8.4 函数的调用 主调函数:主动去调用其它函数 被调函数:被其它函数所调用 8.4.1 函数调用的一般形式函数名(实参表列) 操作:把控制和实参传送给被调函数,当无参时,实参表列为空,但( )不能省。 函数名:是已存在的被调用的函
13、数; 实参表列:有确定值的数据,当有多个实参时,实参间用“ ,”分隔,通常形实、参个数要相等,类型要一致,实参求值顺序在Turbo C中是从右向左。,例T8-4.c 实参求值顺序从右向左 main( ) int i=2, p;p=f(i, +i); printf(“p=%d, i=%d n”,p, i); int f(int a, int b) int c; if(ab) c=1; else if(a=b) c=0; else c=-1; return (c); ,运行结果:p=0, i=3 若将参数改为f(i,i+), 则结果为:p=1, i=3 思考:若从左至右呢? 回忆一下printf的
14、求值顺序,8.4.2 函数的调用方法 1.函数语句:把函数调用作为一个单独的语句; 如:f1( ); 2.函数表达式:函数调用出现在表达式中,其函数返回的值参加整个表达式的运算。如:c=max(a,b) + min(c,d); 3.函数参数:函数调用作为另一个函数的参数,如:m=max(a,max(b,c); printf(“%d”,max(a,b);,8.4.3 对被调用函数的声明和函数原型 被调函数应具备的条件 1.被调函数必须存在(标准或用户定义),如不在同一文件中,可用项目或文件包含的方法将各被调用函数连接起来。 2.若使用库函数,应在文件开头用#include命令将调用库函数时用到的
15、宏定义信息包含到本文件中来。如:#include “stdio.h” #include “math.h” 3.若主调和被调函数在同一文件中,一般应在主调函数中对被调函数的类型作声明,即向编译系统声明即将调用的函数 形式:类型标识符 被调用函数名(类型 形参. );,例T8-5.c 在主调函数中,对被调函数的数据类型进行说明 main( ) float add( float x,float y ); /*声明:函数类型、名,形参类型等通知编译系统*/ 再看float a, b, c; scanf(%f%f”, ,输入:3.6 6. 5 输出:sum is 10.10000,问题: (1)若不对函
16、数类型进行声明,则指出:在重定义函数add时,类型不匹配; (2)在声明时指出类型,若定义时没有指出类型,编译指出:定义add时类型不匹配(此处是实型)。 函数声明(原型):与函数首部一致。 顺序、个数、类型等都要相同 有关函数的定义、声明、返回值等概念 1.函数定义:对函数功能的确定,指定函数名、函数值类型、形参及类型、函数体等,它是完整的、独立的函数单位。,2.函数声明:也称函数原型,其作用是把函数的名字、函数类型以及形参的类型、个数和顺序通知编译系统,以便调用函数时进行对照检查。 函数声明(原型)的形式: (1)函数类型 函数名(参数类型1,参数类型2.); (2)函数类型 函数名(参数
17、类型1 参数名1,参数类型2 参数名2.); 3.当函数返回的值为整型或字符型时,可不必声明。系统会默认把第一次碰到的函数视为INT 4.被调用函数在主调函数之前定义时,在主调函数中可不必声明。,友情提示1,函数的原型声明必须放在程序开始处或main之前,例T8-5-1.c被调函数出现在主调函数之前,则在主调函数中不必声明 float add(float x,float y) float z; z=x+y; return(z); main( ) float a, b, c; scanf(“%f%f”, ,输入:3.6 6.5 输出:sum is 10.100000,主调函数中没对被调函数的返回
18、值进行类型声明,原因是: 编译系统已经预知定义的函数的类型,并进行自动处理。 5.如果在所有函数定义之前,在文件的开头,在函数的外部对函数的类型作了声明,则在各主调函数中不必对所调用的函数再作类型声明。例T8-5-2.c 在文件的开头,在所有函数的外部对函数作类型声明 。 char a1(char x1,char x2 ); float a2(float y1,float y2 ); int a3( int m ); double a4( double n1,double n2 );,main( ) 返回 char c1=d, c2=a; int i=5; float f1=3.67, f2=
19、5.56; double d1=11111111.111, d2=22222222.222; printf(“a1( )=%c n”, a1(c1, c2); printf(“a2( )=%f n”, a2(f1, f2); printf(“a3( )=%d n”, a3(i);printf(“a4( )=%lf n”, a4(d1, d2); char a1(char x1, char x2) return( x1x2 ? x1 : x2); float a2(float y1, float y2) float z; z=y1+y2; return( z ); int a3(int m) i
20、nt i, s=1; for(i=1; i=m; i+)s=s*i; return(s) ; double a4(double n1,double n2) double n3; n3=n1+n2; return(n3); ,运行结果: a1( )=d a2( )=9.230000 a3( )=120 a4( )=33333333.333000问题的提出: (1)不在文件开头,不在 函数外部说明,情况如何? (2)不在主调函数开始部 分说明,解决的办法?,友情提示2,不要将空函数和void函数弄混了,8.5 函数的嵌套调用,例T8-6 用弦截法求方程 x3 -5x2 +16x =0 的根(请仔细
21、研究),方法与步骤: 2.连接f(x1),f(x2)两点成一直线(弦),此线交x轴于x。X点的坐标求法: 连接f(x1),f(x2)两点的直线 f(x) 称商差(弦、斜率): 求x点的坐标 从x值得f(x) 3.若f(x)与f(x1)同号,则根必在(x,x2)区间,此时将x作新的x1; 若f(x)与f(x2)同号,则根必在(x1,x)区间,此时将x作新的x2; 4.重复步骤2,3直到| f(x) | 为止, 设 10-6 , 则 f(x)0,异号:x1,x2之间必有一根 1.取x1,x2两点 得f(x1), f(x2) 同号:改变x1, x2,直到f(x1), f(x2)异号为止。,用三个函数
22、实现各部分的功能: f(x):用来求x的函数:x3 - 5x2 +16x-80 xpoint(x1,x2): 求f(x1)与f(x2)的连线(弦)与x轴交点x的坐标 root(x1, x2) :求(x1, x2)区间的实根 例T8-6.c 用弦截法求方程x3 - 5x2 +16x-80的根 #include “math.h” float f(float x) float y; y=(x-5.0)*x+16.0)*x-80.0; return(y); float xpoint(float x1, float x2) float y; y=(x1*f(x2)-x2*f(x1)/(f(x2)-f(x
23、1); return(y); ,float root(float x1,float x2) float x, y, y1; y1=f(x1);dox=xpoint(x1, x2); y=f(x);if(y*y1 0) y1=y; x1=x; else x2=x; while(fabs(y) =0.0001);return(x); main( ) float x1, x2, f1, f2, x;do printf(“input x1, x2: n”); scanf(“%f%f”, ,运行: input x1, x2:2, 6A root of equation is 5.0000,8.6 函数的
24、递归调用 递归:在函数调用过程中,直接或间接的调用自身。 1.直接递归:在函数体内又调用自身,2.间接递归:当函数去调用另一函数时,而另一函数反过来又调用自身。解决无终止递归调用的方法是:确定好结束递归的条件。,递归调用 定义:函数直接或间接的调用自身叫函数的递归调用,说明 C编译系统对递归函数的自调用次数没有限制 所以,必须要用if 语句限制递归的次数,以免无限递归下去了,int f(int x) int y,z;z=f(y);.return(2*z); ,例T8-7.c 有5个人在一起问年龄,第5个人比第4个人大2岁,第4个人比第3个人大2岁. . .第2个人比第1个人大2岁,第1个人为1
25、0岁。(回推+递推),T8-7.c 问年龄程序 age(int n) int c; if(n=1) c=10; else c=2+age(n-1); return(c); /*返回给主调函数*/ main( ) printf(“%d n”, age(5); ,运行结果:18,在递归调用过程中,有些信息被临时压入堆栈 回推到已知:结束这里控制有限次递归的一个条件就是if (n=1),有些问题,可以用递推,也可以用递归的方法解决 递推:从一个已知的事实出发,按一定规律推出下一个事实,再从已知的新的事实,推出下一个新的事实. 例T8-7-1.c 用递推法求n! ,即从1开始, 乘2, 乘3一直到n
26、main( ) int i, s=1; for(i=1;i=5;i+) s=s* i; printf(“s=%d n”,s); ,运行结果:s=120,递归:回推(问题先压入堆栈暂存)+递推 从哪里开始递推?从满足结束递归的条件处开始递推如: 5!=5 x 4! 4!=4 x 3! 3!=3 x 2! 2!=2 x 1! 1!=1 0!=1,例T8-8.c 用递归法求4! float facto(int n) float s; if(n 0) printf(“ n 0 data error ! n”); else if(n=0 | n=1 ) s=1;else s=n*facto(n-1);
27、return(s); main( ) int n; float y; printf(“input a integer number:”); scanf(%d”, ,facto(int n) int s;if(n= =0)s = 1;else s=facto(n-1);s=n*s;return(s); ,facto(int n),int s;,if(n= =0),facto(int n) int s;if(n= =0)s = 1;else s=facto(n-1);s=n*s;return(s); ,s=facto(n-1),facto(int n),int s;,if(n= =0),facto
28、(int n) int s;if(n= =0)s = 1;else s=facto(n-1);s=n*s;return(s); ,s=facto(n-1),facto(int n) int s;if(n= =0)s = 1;else s=facto(n-1);s=n*s;return(s); ,facto(int n),facto(int n),int s;,int s;,if(n= =0),if(n= =0),s=facto(n-1),s = 1,return(1),s=n*s=2*1,return(2),return(6),s=n*s=3*2,s=n*s=4*6,return(24),1,
29、2,3,4,3,2,1,N=4,N=3,N=2,N=1,facto(int n) int s;if(n= =0)s = 1;else s=facto(n-1);s=n*s;return(s); ,facto(int n),int s;,else,s=facto(n-1),2,N=4,main函数第 1次调用facto,(main),堆栈,(n=4),facto(int n) int s;if(n= =0)s = 1;else s=facto(n-1);s=n*s;return(s); ,N=3,facto(int n),int s;,else,s=facto(n-1),3,Facto1函数第
30、2次调用facto,(main),堆栈,(n=4),(n=3),facto(int n) int s;if(n= =0)s = 1;else s=facto(n-1);s=n*s;return(s); ,N=2,facto(int n),int s;,else,s=facto(n-1),4,Facto2函数调用 第3次facto,(main),堆栈,(n=4),(n=3),(n=2),facto(int n) int s;if(n= =0)s = 1;else s=facto(n-1);s=n*s;return(s); ,N=1,facto(int n),int s;,else,s=facto
31、(n-1),4,Facto3函数第 4次调用facto,(main),堆栈,(n=4),(n=3),(n=2),(n=1),facto(int n) int s;if(n= =0)s = 1;else s=facto(n-1);s=n*s;return(s); ,s = 1,N=0,facto(int n),int s;,if(n= =0),Facto4函数第 5次调用facto,return(1),(main),堆栈,(n=4),(n=3),(n=2),(n=1),facto(int n) int s;if(n= =0)s = 1;else s=facto(n-1);s=n*s;return
32、(s); ,s=facto(1-1)=0!=1,s=1*1,return(1),N=1,(main),堆栈,(n=4),(n=3),(n=2),恢复facto4 现场,40E2(n=1),0!= 1,facto(int n) int s;if(n= =0)s = 1;else s=facto(n-1);s=n*s;return(s); ,s=facto(2-1)=1!=1,s=2*1,return(2),N=2,(main),堆栈,(n=4),(n=3),恢复facto3 现场,40E2(n=2),1!= 1,facto(int n) int s;if(n= =0)s = 1;else s=f
33、acto(n-1);s=n*s;return(s); ,s=facto(3-1)=2!=2,s=3*2,return(6),N=3,(main),堆栈,(n=4),恢复facto2 现场,2!= 2,40E2(n=3),facto(int n) int s;if(n= =0)s = 1;else s=facto(n-1);s=n*s;return(s); ,return(24),N=4,s=facto(4-1)=3!=6,s=4*6,(main),堆栈,恢复facto1 现场,3!= 6,40E2(n=4),返回主函数,例T8-9.c hanoi (汉诺)塔问题(请仔细研究) 十九世纪未,欧洲
34、珍奇商店出现一种汉诺塔游戏,并有推销材料,说是古代印度布拉玛庙里的僧侣们当时正在玩这种游戏,如果游戏结束,世界未日即来临。 一、规则及分析: n个盘子从一个座移到另一个座,每次只能移动一个盘子,不允许大盘在小盘上面。 共有三个座,n个盘子由A座移到C座,需移动的次数是2n -1, 若64个盘子移动的次数为: 264 - 1=18, 446, 744, 073, 709, 551, 615 一年的秒数是:365 x 24 x 60 x 60=31536000 1844674407370955161531536000 =584942417355年 即:5849亿年, 从能源角度推算, 太阳系寿命只
35、有150亿年,二、方法与步骤 1.将A上n-1个盘子借助C座移到B座 2.把A上剩下一个盘子送到C座 3.将n-1个盘子从B座借助A座移到C座,三、实例:将A上3个盘子移到C 步骤:1.A座上两个盘子借助C座移到B座2.A座上最后一个盘子移到C座3.B座上两个盘子借助A座移到C座 第一步进一步分解: 1.1 A座上一个盘子从AC 1.2 A座上一个盘子从AB 1.3 C座上一个盘子从CB 第二步进一步分解: A座上最后一个盘子从AC 第三步进一步分解: 3.1 B座上一个盘子从BA 3.2 B座上一个盘子从BC 3.3 A座上一个盘子从AC,结论: 13步都是把n-1个盘子从一个座移到另一个座
36、上,方法一样,只是座的名称不同而已,为使之一般化,将13步表示为:将one 座上的n-1个盘子移到two座,借助 three座,只是对应关系不同。 第一步对应关系:one A two B three C 第三步对应关系:one B two C three A,1.将 n - 1个盘子从一个座移到另一个座上(n - 1) 2.将 1个盘子从一个座移到另一个座上(n - 1),例T8-9.c 用递归的方法解决汉诺塔程序如下: void move(char x, char y) printf(“%c%c n”, x, y); void hanoi(int n, char one, char two,
37、 char three) if(n = 1) move(one,three);else hanoi(n-1, one, three, two); move(one, three); hanoi(n-1, two, one, three); main( ) int m; printf(“input the number of diskes:”); scanf(“%d”,运行: input number of diskes: 3 the step to moving 3 diskes:A CA BC BA CB AB CA C,8.7 数组作为函数参数 函数调用形式一:函数名(数组名)实参或形参
38、函数调用形式二:函数名(数组元素)实参 数组名作为参数:传递的是数组的首地址; 数组元素作实参时:传递的是数组元素的值,是单向的值传送。,8.7 数组作为函数参数 函数调用形式一:函数名(数组名)实参或形参 函数调用形式二:函数名(数组元素)实参 数组名作为参数:传递的是数组的首地址; 数组元素作实参时:传递的是数组元素的值,是单向的值传送。,数组元素作函数实参值传递,例 两个数组大小比较,n=0 m=0 k=0,a和b为有10个元素的整型数组 比较两数组对应元素 变量n,m,k记录aibi, ai=bi, aik,认为数组ab若nk,认为数组ab若n=k,认为数组a=b,2、数组名作为函数实
39、参 此时,传送的是数组的地址,调用函数时,对形参数组元素的操作,实际上也是对实参数组元素的操作。*地址传递 *在主调函数与被调函数分别定义数组,且类型应一致,例 求学生的平均成绩,#include float average(int stu10, int n);void main() int score10, i;float av;printf(“Input 10 scores:n“);for( i=0; i10; i+ )scanf(“%d“, ,float average(int stu10, int n) int i;float av,total=0;for( i=0; in; i+ )
40、total += stui;av = total/n;return av;,实参用数组名,形参用数组定义, int stu ,几点说明: 1.数组名作形、实参数时,应分别在主、被调函数中对其定义 2.数组名作参数时,传递的是地址,对形参数组的操作实际上也是对实参数组的操作。两个数组是共用同一个内存单元则形参中的数据变化了实参也会变化这与变量做形参区别很大 3.作为形、实参数的数组,其类型要一致,大小一般相等,以保证形式上的对应; 4.当形参数组大小未指定时,用一实参将数组长度传递给形参以便对数组进行操作; 5、字符串的传递同数组的传递字符串是用数组存储的,例8-12.c 求两组学生的平均成绩,
41、形参数组长度缺省 float average(float a ,int n) int i; float aver, sum=a0; for(i=1;in;i+) sum=sum+ai; aver=sum/n; return(aver); ,main( ) float s15=98.5, 97, 91.5, 60, 60, 55; float s210=67.5, 89.5, 99, 69.5, 77, 89.5, 76.5, 54, 60, 99.5; printf(“the average of class A is%6.2f n”,average(s1,5); printf(“the av
42、erage of classB is %6.2f n”,average(s2,10); ,the average of class A is 80.40 the average of class B is 78.20,例 数组元素与 数组名作函数参数比较,#include void swap2(int x,int y) int z;z=x; x=y; y=z; main() int a2=1,2;swap2(a0,a1);printf(“a0=%dna1=%dn“,a0,a1); ,值传递,#include void swap2(int x) int z;z=x0; x0=x1; x1=z;
43、main() int a2=1,2;swap2(a);printf(“a0=%dna1=%dn“,a0,a1); ,地址传递,例 数组元素与 数组名作函数参数比较,例 数组排序-简单选择排序(请同学们自行思考),9,49,i=0,例 数组排序-简单选择排序,13,68,i=1,i=8,例 数组排序-简单选择排序,例 求二维数组中最大元素值,int max_value(int array34) int i,j,k,max;max=array00;for(i=0;imax)max=arrayij;return(max); main() int a34=1,3,5,7,2,4,6,8,15,17,3
44、4,12;printf(“max value is %dn“,max_value(a); ,例 求二维数组中各行元素之和,get_sum_row(int x3, int result ,int row, int col) int i,j;for(i=0;irow;i+) resulti=0;for(j=0;jcol;j+)resulti+=xij; main() int a23=3,6,9,1,4,7;int sum_row2,row=2,col=3,i;get_sum_row(a,sum_row,row,col);for(i=0;irow;i+)printf(“The sum of row%
45、d=%dn“,i+1,sum_rowi); ,18,12,8.8 局部变量和全局变量 8.8.1 局部变量 变量:按其作用域,可分为局部和全局 局部:作用域仅限于其所定义的函数或复合语句内部,离开该函数或复合语句则释放内存单元 特点: (1)在不同的函数中允许同名,它们占据不同的内存单元,相互之间互不影响。(2)形参属局部变量,只能在其所在的函数内部使用。,例T8-14-1.c f1( ) int a=10, b=25, c=30; printf(“f1: a=%d, b=%d, c=%d n”, a, b, c); f2( int a,int b ) int c; a=a+2; c=a+b+
46、3; printf(“f2:a=%d, b=%d, c=%d n”,a,b,c); main( ) int a=1, b=2, c=5; /*abc也不例外,也是局部变量*/ printf(“1.main:a=%d, b=%d, c=%d n”,a, b, c); f1( ); printf(“2.main:a=%d, b=%d, c=%d n”,a, b, c); f2(a, b ); printf(“3.main:a=%d, b=%d, c=%d n”,a, b, c); ,运行结果: 1. main:a=1, b=2, c=5f1:a=10, b=25, c=302.main:a=1, b=2, c=5f2:a=3, b=2, c=83.main:a=1, b=2, c=5,