黑马程序员——用函数实现模块化程序设计(二)
用函数实现模块化程序设计(二)
***一、函数的嵌套调用***
C语言的函数定义是互相平行、独立的。即函数不能嵌套定义,但可以嵌套调用函数。即调用一个函数的过程中,又可以调用另一个函数
执行过程,如图:
例子:输入4个整数,找出其中最大的数。用函数的嵌套调用来处理。
解题思路:
main中调用max1函数,找4个数中最大者
max1中再调用max2,找两个数中的大者
/* 输入4个整数,找出其中最大的数。用函数的嵌套调用来处理。 */
#include "stdio.h"
void main()
{
int max1(int a,int b,int c,int d); /*对max1的声明*/
int a,b,c,d,max;
printf("请输入四个数字:");
scanf("%d,%d,%d,%d",&a,&b,&c,&d);
max=max1(a,b,c,d); /*调用max1函数,得到其中最大值,赋值给max*/
printf("max=%d \n",max);
return 0;
}
int max1(int a,int b,int c,int d)/*定义max1函数*/
{
int max2(int a,int b); /*max2的声明*/
int m;
m=max2(a,b); /*调用max函数,找出a和b的最大值*/
m=max2(m,c); /*调用max函数,找出m和c的最大值*/
m=max2(m,d); /*调用max函数,找出m和d的最大值*/
return(m); /*函数返回值是4个数的最大的*/
}
int max2(int a,int b)/*定义max2函数*/
{ if(a>=b)
return a;
else /*函数返回值是a和b中的大的*/
return b;
}
***二、函数的递归调用***
概念:在调用一个函数的过程中又出现直接或间接地调用该函数本身,称为函数的递归调用。
例如:
int f(int x)
{
int y,z;
z=f(y);
return (2*z);
}
在调用f函数过程中,又调用f函数
练习1:有5个学生坐在一起,问第5个学生多少岁?他说比第4个学生大2岁,问第4个学生岁数,他说比第3个学生大2岁,问第3个学生,又说比第2个学生大2岁,问第2个学生,说比第1个学生大2岁,最后问第1个学生,他说是10岁,请问第5个学生多大
解题思路:要求第5个年龄,就必须先知道第4个年龄
要求第4个年龄必须先知道第3个年龄
以此类推age(5)=age(4)+2
age(4)=age(3)+2
…….. age(n)=age(n-1)+2
1 #include <stdio.h> 2 3 void main() 4 5 { 6 7 int age(int n); 8 9 printf("第五个人的年龄:%d\n",age(5));/*输出年龄*/ 10 11 } 12 13 int age(int n)/*求年龄的递归函数*/ 14 15 { 16 17 int c;/*变量c用做存放函数的返回值的变量*/ 18 19 if(n==1) 20 21 c=10; 22 23 else 24 25 c=age(n-1)+2;/*执行age函数过程中又调用age函数*/ 26 27 return(c); 28 29 }
运行结果:18
当主函数的位置在age函数以后,主函数不用再对age函数进行声明
age函数共被调用5次,其中四次是在age函数中调用,也就是递归调用4次,另一次是在主函数中使用的。
练习2:用递归方法求n!。
解题思路:递归的思路跟递推是相反的,是直接从目标出发解决,要求n!必须知道n-1,才能求出n!=(n-1)!*n。所以递归公式为:
n!=1 (n=1或n=0)
n!=n*(n-1)! (n>1)
/*用递归方法求n!*/
1 #include <stdio.h> 2 3 int main() 4 5 {int fac(int n);/*对被调函数fac声明*/ 6 7 int n; int y; 8 9 printf("请输入n的值:"); 10 11 scanf("%d",&n); 12 13 y=fac(n);/*调用fac函数*/ 14 15 printf("%d!=%d\n",n,y); 16 17 return 0; 18 19 } 20 21 int fac(int n)/*定义fac函数*/ 22 23 { 24 25 int f; 26 27 if(n<0) 28 29 printf("数据错误");/*如果输入的n<0,则不正确*/ 30 31 else if(n==0||n==1) 32 33 f=1;/*当n=1或n=0时等于1*/ 34 35 else f=fac(n-1)*n;/*递归调用fac*/ 36 37 return(f);/*f就是n!*/ 38 39 }
/*再求n!的时候一定要记得int数值范围,防止溢出*/
***三、内部函数与外部函数***
1)内部函数概念:如果一个函数只能被本文件中其他函数所调用,它称为内部函数
在定义内部函数时,在函数名和函数类型的前面加static,即:static 类型名 函数名(形参表)
2)外部函数概念:如果在定义函数时,在函数首部的最左端加关键字extern,则此函数是外部函数,可供其他文件调用。
如函数首部可以为extern int fun (int a, int b)
如果在定义函数时省略extern,则默认为外部函数
***四、进制之间的转换***
十进制转换为——>二进制:如6的二进制,算法
结果就为:0110,注意:结果要从下往上写。
二进制转化为——>十进制:如0110的十进制等于:22*1+21*0+20*0=6。
简而言之:十进制转二进,除2取余数;二进制转换为十进制,乘以2的幂数。
十进制--->八进制
10进制数转换成8进制的方法,和转换为2进制的方法类似,唯一变化:除数由2变成8。
十进制--->十六进制
10进制数转换成16进制的方法,和转换为2进制的方法类似,唯一变化:除数由2变成16。
- 十进制:0-9,满10进1。
- 八进制:0-7,满8进1,用0开头表示。
- 十六进制:0-9,A-F,满16进1,用0x开头表示。