《《C语言函数》PPT课件》由会员分享,可在线阅读,更多相关《《C语言函数》PPT课件(50页珍藏版)》请在金锄头文库上搜索。
1、,模块化程序设计,函数 孙小松,06.09.2020,1,.,2,6.1 函数的概念,C程序结构,C程序结构如图所示 1.一个C程序可以分为若干个函数 2.每个程序有且只有一个主函数(main),其他都是子函数 3.子函数可以相互调用,但主函数不能被调用 4.一个C源程序由一个或多个文件构成,每个文件就是一个编译单位,.,3,说明: 1.一个C程序的执行从主函数(main)开始,调用其他函数后仍回到main主函数结束. 2.每个子函数都是平行的,任何子函数都不从属于其他函数 3.从用户角度,函数可以分为: 标准函数,即库函数 用户自定义函数 4.从函数形式可以分为: 无参函数:printsta
2、r() 有参函数:printf(“hello”),#include void printStar() printf(“*n”); void printMessage() printf(“Hello, world.n”); printStar(); void main() printStar(); printMessage(); ,.,4,函数定义的一般形式,函数定义的一般形式: 类型说明 函数名(形式参数说明) 函数体 形式参数说明方法: 数据类型 变量名,类型 变量名,无参数函数定义形式: 类型说明 函数名() 函数体 ,void printHello() printf(“hello!n”)
3、; ,有参数函数定义形式: 类型说明 函数名(形式参数说明) 函数体 ,int sum(int x, int y) int z; z=x+y; return(z); ,.,5,函数体 一般情况下,函数体有两部分组成: 局部变量说明 语句; 局部变量说明: 函数体内的变量.其有效范围仅在本函数体内起作用,离开本函数无意义.,int sum(int x, int y) int z; /局部变量定义 z=x+y; return(z); ,.,6,函数的参数和函数的值,一个程序由若干个函数组成,各函数调用时经常要传递一些数据,即调用函数把数据传递给被调用函数,经过被调用函数处理后,得到一个确定的结果,
4、在返回调用函数时,将结果带回调用函数.,#include int max(int x, int y) int z; z=(xy) ? x : y; return(z); void main() int a,b,c; scanf(“%d%d”, ,主函数,子函数,. . c = max(a,b); . .,int max (intx, int y) . . . return (z);,各函数之间数据往来通过参数传递和返回语句实现,.,7,函数参数:用于函数间数据的传递 形式参数:定义函数时给出的参数 实际参数:调用函数时给出的参数,#include int max(int x, int y) i
5、nt z; z=(xy) ? x : y; return(z); void main() int a,b,c; scanf(“%d%d”, ,对于函数max有两个形式参数x,y 形式参数x和y只在max函数中使用,a,b是主函数中定义的变量, 当main函数调用 max函数时. a,b成为max的实际参数 调用时, 实际参数的值赋给形参进行处理,例: max接受到两个值: 89 max返回89,一、形式参数和实际参数,.,8,#include int max(int x, int y) int z; z=(xy) ? x : y; return(z); void main() int a,b,
6、c; scanf(“%d%d”, ,说明: 1.定义函数时,必须说明形参的类型,形参只能 是变量(包括数组). 不能是常量或表达式,2.函数被调用之前,形参和子函数中的变量 不占内存,调用结束返回,形参所占的内存被收回.,3.实参可以是常量、变量或表达式. 因为传递过来的是具体数值.,4.实参和形参类型必须一致(或可以安全转换).,5.C语言中,实参和形参传递的是”按值传递”, 即单向传递, 只与参数相对位置有关,而与 变量名无关,int b, int a,int c; c=( ab ) ? a :b; return(c);,13,20,main-a,main-b,max-a,max-b,13
7、,20,.,9,#include int sum(int a, int b) a=a+b; b=a+b; return(a); void main() int a=1,b=3,c; c=sum(a,b); printf(“sum of %d,%d is %dn”,a,b,c); ,阅读下面程序,写出运行结果,函数被调用之前,形参和子函数中的变量 不占内存,调用结束返回,形参所占的内存被收回.,实参和形参传递的是”值传递”, 即单向传递, 只与参数相对位置有关,而与 变量名无关,sum of 1,3 is 4,.,10,二、函数返回值,#include int max(int x, int y)
8、 int z; z=(xy) ? x : y; return(z); void main() int a,b,c; scanf(“%d%d”, ,函数值也就是函数的返回值,是一个 具体确定的值.,函数使用return语句返回值。,一个函数内可以有多个return语句, 执行到任何return语句,函数都将立即 返回到调用函数,if(xy) return(x); else return(y);,return后面的()可以省略,可以返回 一个表达式,先求解表达式的值,再返回.,int max(int x, int y) return xy?x:y; ,1.返回函数值的方法,.,11,#includ
9、e int max(int x, int y) int z; z=(xy) ? x : y; return(z); void main() int a,b,c; scanf(“%d%d”, ,2.函数值的类型,函数的类型即函数值的类型.例如,函数 max是int型,函数的返回值也是int型.,省略了类型说明的函数就是int型.,return中表达式的值一般和函数类型相同.,如果不一致,则需要进行类型转换.以 函数类型为准.,.,12,3.不需要返回的函数,如果函数中没有return, 认为是 一个过程,可以使用类型void.,如果一个函数被声明void类型,就不允许 再引用它的返回值。只能单纯
10、调用它。,#include void printStar() printf(“*n”); void printMessage() printf(“Hello, world.n”); printStar(); void main() printStar(); printMessage(); ,.,13,函数的调用,一、函数调用一般形式,一般形式: 函数名(实参列表),说明: 如果调用无参函数,实参表列可以忽略, 但括号不能省.,实参个数和形参个数相同.,实参和形参类型一一对应,必要时会进行类型转换.,注意:不同系统中,实参的计算顺序不同. 一般认为从右到左计算和赋值. 一般在调用函数前计算出实参
11、的值,例1 读程序,写出结果 #include int f(int a, int b) int c; if(a b) c = 1; else if(a = b) c = 0; else c = -1; return c; void main() int i = 2, p; p = f(i, +i); printf(“%d”, p); ,.,14,二、函数调用方式,1、函数语句 形式为:函数(实参表列);,例如: printMessage(); printf(“%d”,p);,说明: 这种方式不要求函数带返回值, 函数只执行一定操作.,2、函数表达式 函数的返回值参与运算,例如: m = max
12、(a,b); m = 3 * max(a,b); printf(“%d”,max(a,b);,说明: 这种方式的函数不能用于void类型,.,15,三、函数调用的执行过程,从右到左的顺序,计算实参中各表达式值.,按照位置,将实参的值一一传递给形参.,执行被调用函数.,当遇到return(表达式)语句时, 计算表达式的值并返回主调函数.,X= -0.600000,iabs(x)=1.000000,.,16,四、函数的原形,在程序中调用函数需满足以下条件: 被调用函数必须存在,且必须遵循 “先定义后使用”的原则,如果被调用函数的定义在主调函数之后,可以在调用之前给出原形说明.,原形说明: 类型说明
13、 函数名(参数类型,参数类型),.,17,函数的嵌套调用,嵌套调用是指在一个函数的函数体中又调用了其他函数.,程序执行过程:,第一层 第二层 第三层 main() printStar() printStar(); printfMessage() printMessage(); printStar(); printStar(); ,结束,#include void printStar() printf(“*n”); void printMessage() printf(“Hello, world.n”); printStar(); void main() printStar(); printMe
14、ssage(); ,.,18,例3 编程求,分析: 重复三次不同的阶乘运算, 只是每次的值不同.,将求阶乘的过程编程一个函数 fac,以不同的参数值来调用fac,#include #include float fac(int k); float t=1.0; int i; for(i=2;i=k;i+) t*=i; return t; void main() float c; int m,n; printf(“input m,n:”); scanf (“%d%d”, ,.,19,许多数学函数都是使用递归调用形式定义的:,函数的递归调用,当n=1时,当n1时,当n=0时,当n!=1时,.,20,
15、函数的递归调用是指在调用一个函数时又直接或间接调用函数本身.,直接调用,间接调用,递归调用必须引入一个循环条件控制递归结束,否则进入死循环.,.,21,例4 有5个人坐在一起,问第5个人多少岁?答:比第4个人大2岁;第4个人说他比第三个人大2岁;第3个人比第2个人大2岁,第2个人比第1个人大2岁.而第1个人有10岁.问第5个人多少岁?,.,22,函数调用过程,#include int age ( int n) int c; if (n=1) c=10; else c=age(n-1) + 2; return c; void main() printf(“ %d “, age(5); ,.,23,例5 用递归调用求n!阶乘(n=0),使用循环做: float fac( int n) float f=1; if (n=0) for(i=2; i=n; i+) f *= i; else f=-1; return f; ,#include float fac (int n) float f; if (n1) f=fac(n-1) * n; else if (n=0|n=1) f=1; else f=-1; return f; void main() int n; float y; print