
程序设计基础 第7章 函数 1/15
第7章 函 数 程序设计基础 1/15

本章知识点 7.1函数概述 7.2函数的定义和使用 7.3嵌套调用与递归调用 7.4变量与函数 7.5随机数函数 恩 2/15
本章知识点 7.1 函数概述 7.2 函数的定义和使用 7.3 嵌套调用与递归调用 7.4 变量与函数 7.5 随机数函数 2/15

嵌套调用与递归调用 嵌套调用 C规定:函数定义不可嵌套,但可以嵌套调用函数,即在 调用一个函数的过程中,又调用另一个函数。 main() main() a函数 b函数 {. a0; ② ④ 调用函数a 调用函数b ⑤ ⑨ void a() 结束 b0: 函数嵌套调用的示意图 void b() } 3/15
嵌套调用与递归调用 C规定:函数定义不可嵌套, 嵌套调用 但可以嵌套调用函数,即在 main( ) 调用函数a 结束 a函数 b函数 调用函数b ——函数嵌套调用的示意图 调用一个函数的过程中,又调用另一个函数。 main() { . a(); . } void a() { b(); } void b() {.} 3/15

对于任意m、n,求Cm” ml 已经组合数公式:Cm= nl(m-n)! (1)用函数cmn(m,n)求组合数: (2)用函数fac(k)求k的阶乘。 main() { main() cmn函数 ac函数 cmnO月 ① ④ 调用cmn函数 调用fac函数 ⑤ double cmn() ⑨ ⑥ 结束 fac(); } double fac() 函数嵌套调用的示意图 } 恩 4/15
对于任意m、n,求Cm n (1)用函数cmn(m,n)求组合数; (2)用函数fac(k)求k的阶乘。 已经组合数公式: main( ) 调用cmn函数 结束 cmn函数 fac函数 调用fac函数 ——函数嵌套调用的示意图 main() { . cmn(); . } double cmn() { fac(); } double fac() {.} !( )! ! n m n m C n m − = 4/15

m 求Cmn的程序 m nl.(m-n)! #include<stdio.h≥ double fac(int k); ∥声明fac0函数求k的阶乘 double cmn(intm,intn);∥声明cmn)函数求组合数 int main() int m,n; double t; printf("Input m n:"); scanf("%d%d",&m,&n); t=cmn(m,n); ∥调用求组合数的函数cmn(0 printf("C(%d,%d)=%lfn",m,n,t); return 0; 猖 5/15
求Cm n 的程序 #include double fac(int k); // 声明fac()函数求k的阶乘 double cmn(int m,int n); // 声明cmn()函数求组合数 int main() { int m,n; double t; printf("Input m n:"); scanf("%d%d",&m,&n); t=cmn(m,n); // 调用求组合数的函数cmn() printf("C(%d,%d)=%lf\n",m,n,t); return 0; } !( )! ! n m n m C n m − = 5/15

Cm= ml 求Cmn的程序 l(m-n)川 double cmn(intm,intn)∥定义cmn)函数求组合数 double res; res=fac(m)(fac(n)*fac(m-n);∥调用fac0函数 return res; double fac(int k) ∥定义fac0函数求k的阶乘 { int i; double f; for(i=1,f=1ji<=k;i++) {f*=i;} return f; 恩 6/15
求Cm n 的程序 double cmn(int m,int n) // 定义cmn()函数求组合数 { double res; res=fac(m)/(fac(n)*fac(m-n)); // 调用fac()函数 return res; } double fac(int k) // 定义fac()函数求k的阶乘 { int i; double f; for(i=1,f=1;i<=k;i++) { f*=i; } return f; } !( )! ! n m n m C n m − = 6/15

函数递归调用 >定义:函数直接或问接的调用自身叫函数的递归调用 int f(int x) int fl (int x) Lint f2 (int t) { int y,Z; int y,Z; int a,c; ◆0e。e z=f(y); z=f2(y); c=fl (a); return (2*Z); return (2*z); return (3+c); f() 1( f2() 直搂归 间接递归 调f 调f2 调f1 >说明 ●C编译系统对递归函数的自调用次数没有限制 ●每调用函数一次,在内存堆栈区分配空间,用于存放函数变量、 返回值等信息,所以递归次数过多,可能引起堆栈溢出 7/15
函数递归调用 ➢ 定义:函数直接或间接的调用自身叫函数的递归调用 f ( ) 调f 调f2 调f1 f1( ) f2( ) ➢ 说明 int f (int x) { int y, z; . z = f (y); . return (2*z); } int f1 (int x) { int y,z; . z = f2 (y); . return (2*z); } int f2 (int t) { int a,c; . c = f1 (a); . return (3+c); } 直接递归 间接递归 ⚫ C编译系统对递归函数的自调用次数没有限制 ⚫ 每调用函数一次,在内存堆栈区分配空间,用于存放函数变量、 返回值等信息,所以递归次数过多,可能引起堆栈溢出 7/15

例:有5个学生坐在一起 >问第5个学生多少岁?他说比第4个学生大2岁 >问第4个学生岁数,他说比第3个学生大2岁 >问第3个学生,又说比第2个学生大2岁 >问第2个学生,说比第1个学生大2岁 >最后问第一个学生,他说是10岁 >请问第5个学生多大? 分析得知:每个学生年龄都比其前一个学生的年龄大2岁。求后一个学生 的年龄必须知道前一个学生的年龄。如果第一个学生年龄知道了,后面 的+2求解。 ·解题思路: age(5)=age(4)+2 age(4)=age(3)+2 age(n)=10 (n=1) age(3)=age(2)+2 age(n)=age(n-1)+2 (n>1) age(2)=age(1)+2 age(1)=10 8/15
• 解题思路: age(5)=age(4)+2 age(4)=age(3)+2 age(3)=age(2)+2 age(2)=age(1)+2 age(1)=10 ( ) ( 1) 2 ( 1) ( ) 10 ( 1) = − + = = age n age n n age n n 例: 有5个学生坐在一起 ➢ 问第5个学生多少岁?他说比第4个学生大2岁 ➢ 问第4个学生岁数,他说比第3个学生大2岁 ➢ 问第3个学生,又说比第2个学生大2岁 ➢ 问第2个学生,说比第1个学生大2岁 ➢ 最后问第一个学生,他说是10岁 ➢ 请问第5个学生多大? 分析得知:每个学生年龄都比其前一个学生的年龄大2岁。求后一个学生 的年龄必须知道前一个学生的年龄。如果第一个学生年龄知道了,后面 的+2求解。 8/15

#include int age(int n) int age(int n); int c; int main() if (n==1) c=10; printf("NO.5,age:%d\n",age(5)); else c=age(n-1)+2; return 0; age(n)=10 (n=1) return c; age(n)=age(n-1)+2 (n>1) age(5) age(4) age(3) age(2) age(1) n=5 n=4 n=3 n=2 n=1 c=age(4)+2 c=age(3)+2 c=age(2)+2 c=age(1)+2 c=10 return c return c return c return c return c c=18 c=16 c=14 c=12 N0.5,age:18 夏 9/15
#include int age(int n); int main() { printf("NO.5,age:%d\n",age(5)); return 0; } int age(int n) { int c; if (n==1) c=10; else c=age(n-1)+2; return c ; } age (5) n=5 c=age(4)+2 age (4) n=4 c=age(3)+2 age (3) n=3 c=age(2)+2 age (2) n=2 c=age(1)+2 age (1) n=1 c=10 return c c=12 return c c=14 return c c=16 return c c=18 return c ( ) ( 1) 2 ( 1) ( ) 10 ( 1) = − + = = age n age n n age n n 9/15

求n的阶乘n! 方法一:利用循还 因为n!=n*(-1)*(-2)*.*2*1,我们完全可以用循环语 句来编写这个非递归函数fact: long fact (int n) 方法二:利用递归 当n=1时 long L=1; int i; -a-y 当n>1时 for(i=1;i<=n;i++) L*=i; long fact (int n) return L; long L; if (n =1) L=1; 程序中用f语句来控制,只有在 else 某一条件成立时才继续执行递归 L=n fact (n-1); 调用,否则就不再继续,这样, return L; 不会出现无终止的递归调用。 0/15
求n的阶乘n! long fact (int n) { long L = 1; int i; for (i = 1; i 1时 long fact (int n) { long L; if (n == 1) L=1; else L = n * fact (n-1); return L; } 程序中用if语句来控制,只有在 某一条件成立时才继续执行递归 调用,否则就不再继续,这样, 不会出现无终止的递归调用。 10/15