第8章 函数参考答案[知识要点]C语言的基本组成单位函数。C是由一个且仅有一个主函数( main)和若干个子函数组成.子函数可有可无。一个C语言源程序[1]执行,从主函数开始,以主函数结束。C语言称为函数式语言[2],即用户可根据解决问题的算法编成一个相对独立的函数模块,然后采用调用的方法来使用函数[3]。采用了函数模块式的结构的特点:程序的层次结构清晰,便于程序的编写、阅读和调试[4]。C语言提供了极为丰富的库函数,使用这些库函数时,在源程序的头部使用文件包含命令。如:数学函数 #include 字符函数 #include 字符串函数 #include 输入输出函数 #include 动态存储分配[5]函数 #include #include 清屏函数 #include 日期和时间函数 #include 函数可以嵌套调用,而不可嵌套定义。函数的值: 函数的值的数据类型[6]由函数定义时所决定的。调用函数时可有返回值和无返回值两种。有返回值的函数在函数体内必有一条或多条 return 语句,无返回值的函数定义为void类型,且在函数体无return 语句。函数调用[7]时参数的传递:主调函数和被调函数之间数据传递有两种,数值传递和地址传递。[习题参考答案]8.1写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果,两个整数由键盘输入。[解析]用碾转相除法求最大公约数。最小公倍数=两个整数之积/最大公约数。#include int gcf(int x,int y) /*求两整数的最大公约数*/(int t,r;if (x{t=x;x=y;y=t;)while ((r=x%y)!=0)( x=y;y=r;)return y;}int lcm(int x,int y,int h) /*求两整数的最小公倍数*/(return(x*y/h);)void main ( )( int a,b,df,sc; /* df:所求的最大公约数,sc:所求的最小公倍数*/printf("Input a,bn");scanf(“%d%d”,&a,&b);df=gcf(a,b);printf(“G.C.F=%dn”,df);sc=lcm(a,b,df);printf(“L.C.M=%dn”,sc);)8.2 求方程ax2+bx+c=0的根,用3个函数分别求当b2-4ac大于0,等于0和小于0时的根,并输出结果。从主函数输入a,b,c的值。# include void real_root(float a,float b,float disc) /*求方程的两个不相同的实根*/(float x1,x2;x1=(-b+sqrt(disc))/(2*a);x2=(-b-sqrt(disc))/(2*a);printf("x1=%5.2ftx2=%5.2fn",x1,x2);)void equal_root(float a,float b) /*求方程的两个相同的实根*/( float x1,x2;x1=x2=(-b)/(2*a);printf("x1=%5.2ftx2=%5.2fn",x1,x2);)void imaginary_root(float a,float b,float disc) /*求方程的两个不相同的虚根*/( float p,q;p=-b/(2*a);q=sqrt(disc)/(2*a);printf("x1=%5.2f+%5.2fitx2=%5.2f-%5.2fin",p,q,p,q);)void main ( )(float a,b,c,disc;printf("nInput a,b,c:n");scanf("%f%f%f",&a,&b,&c);disc=b*b-4*a*c;if (disc>0)real_root(a,b,disc);else if (disc==0)equal_root(a,b);elseimaginary_root(a,b,disc);)8.3写一个判素数的函数,在主函数输入一个整数,输出是否素数的信息。[解析]:素数(质数):只能被1和该整数本身整除的数为素数。换句话说,只有两个正因数(1和自己)的自然数即为素数。#include int prime(int n)(int flag=1,i; /*flag:标识变量*/for (i=2;i<=n/2 && flag==1;i++)if (n%i==0)flag=0;return flag ;)void main ( )(int n;printf("nInput an integer:");scanf("%d",&n);if (prime(n))printf("n %d is a prime.",n);elseprintf("n %d is not a prime.",n);)[扩展]求100以内的所有的素数。#include int prime(int n)(int flag=1,i; /*flag:标识变量*/for (i=2;i<=n/2 && flag==1;i++)if (n%i==0)flag=0;return flag ;)void main ( )(int a[100],i,j=0;for(i=2;i<=100;i++)a[i]=i;for(i=2;i<=100;i++)if (prime(a[i])){ if(j++%5==0) printf("n"); /*控制每行输出的个数,每行按5个输出*/printf("%5d",a[i]);)}8.4写一函数,使给定的一个二维数组(3×3)转置,即行列互换。# define N 3#define M 3#include void fun (int a[N][M],int b[M][N])( int i,j,t;for (i=0;ifor (j=0;jb[j][i]=a[i][j];)void main ( )( int i,j,a[N][M],b[M][N];printf("Input %d * %d array:n",N,M);for (i=0;ifor (j=0;jscanf("%d",&a[i][j]);printf("Original array : n");for (i=0;i{for (j=0;jprintf("%4d",a[i][j]);printf("n");)fun(a,b);printf("Convert array:n");for (i=0;i(for (j=0;jprintf("%4d",b[i][j]);printf("n");)}[解析]字符串处理方法,一是字符数组,二是指针,编写函数时,采用地址传递。#include #include void inverse (char str[ ])(char t;int i,j;for (i=0,j=strlen(str)-1;i{ t=str[i];str[i]=str[j];str[j]=t;)}void main ( )(char str[80];void inverse (char str[ ]);printf(“Input string:”);gets(str);inverse(str);puts(str);)8.6写一函数,将两个字符串连接。[解析]:将串2连接在串1 的后面,形成一新串。新串末尾须加字符串结束标志。#include #include char connect(char str1[ ],char str2[ ])(int i,j;for (j=strlen(str1),i=0;str2[i]!='0';i++)str1[i+j]=str2[i];str1[i+j]='0'; /*新串末尾须加字符串结束标志0*/)void main ( )( char s1[80],s2[80];printf("nInput string1:");gets(s1);printf("nInput string2:");gets(s2);connect(s1,s2);puts(s1);) ng is %sn”,s);}8.7 写一个函数,将一个字符串中的元音字母复制到另一个字符串,然后输出。#include #include void string_copy(char str[])( int i,j=0;for(i=0;str[i]!='0';i++)if(str[i]=='a'||str[i]=='e'||str[i]=='i'||str[i]=='o'||str[i]=='u')str[j++]=str[i];str[j]='0';puts(str);)void main ( )( char str[80];int n;gets(str);string_copy(str);)8.8写一函数,输入一个4位数字,要求输出这4个数字字符,但每两个数字之间有一个空格。如输入1990,应输出”1 9 9 0”。#include #include void change(int n,char str[]) /* 该函数的功能将数值转换为数字字符*/( int i;for(i=3;i>=0;i--){ str[i]=n%10+'0';n/=10;)str[4]='0';}void insert(char str[]) /* 该函数的功能插入空格并输出该数字字符*/( int i;for (i=strlen(str);i>0;i--){ str[2*i]=str[i];str[2*i-1]=' ';scanf("%d,%d",&a,&n);printf("a=%d n=%d n",a,n);while(count<=n){tn=tn+a;sn=sn+tn;a=a*10;++count;)printf("a+aa+aaa+…=%dn",sn);}6.4 求 (即1+2!+3!+4!+…+20!)void main()(float n,s=0,t=1;for(n=1;n<=20;n++){t=t*n;s=s+t;)printf("1!+2!+…+20!=%en",s);}阶乘利用递归,再求和:#includeusing namespace std;long Func(int n)(if(1==n)return n;if(n>1)return n*Func(n-1);)main()(long s=0;int i=1;while (i<=6){s=s+Func(i);i++;)cout<}6.5 求 。void main()(int k,N1=100,N2=50,N3=10;float s1=0.0,s2=0.0,s3=0.0;for(k=1;k<=N1;k++)/*计算1到100的和*/{s1=s1+k;)for(k=1;k<=N2;k++)/*计算1到50各数平方和*/(s2=s2+k*k;)for(k=1;k<=N3;k++) /*计算1到10各数倒数之和*/(s3=s3+1.0/k;)printf("总和=%8.2fn",s1+s2+s3);}已通过int main()(int k=1,i=11,j=51;float s=0.0;while(k<=10){s=s+k+k*k+1.0/k;while(k==10 && i<=50){s=s+i+i*i;)puts(str);}void main ( )( char str[80];int n;printf("nInput number :");do /* 该循环控制输入的数为四位整数*/scanf("%d",&n);while(n<999||n>10000);change(n,str);insert(str);)8.9编写一函数,有实参[8]传来一个字符串,统计此字符串中字母,数字,空格和其它字符的个数,在主函数中输入字符串以及输出上述的结果。#include #include #include int letter,digit,space,others; /* 说明定义为全局变量[9],全局变量不赋值时自动赋0值 */int count(char str[ ])(int i;for (i=0;str[i]!='0';i++)if (isalpha(str[i]))letter++;else if (isdigit(str[i]))digit++;else if (str[i]==' ')space++;elseothers++;)void main ( )(char str[80];printf("nInput string:n");gets(str);printf("string:");puts(str);count(str);printf("letter:%d,digit:%d,space:%d,others:%dn",letter,digit,space,others);)8.10写一函数,输入一行字符,将此字符串中最长的单词输出。[解析]先确定单词是如何组成的。假若以空格、数字或其它字符作为单词的分隔。#include #include #include char string_long(char str[])(int i,j,k=1,flag=1,max=0,si=0,sj;for(i=0;str[i]!='0';i++){ if(isalpha(str[i]))if(flag){ j=i;flag=0;)elsek++;else(if(max{ max=k;si=j; /* si :记长串的起始位置*/sj=si+k; /* sj :记长串的结束位置*/)flag=1;k=1;}}str[sj]='0';puts(&str[si]);}void main ( )( int i;char string[80];printf("Input one line character:n");gets (string);printf("nThe longest word is :");string_long(string);)8.11写一函数,用“起泡法”对输入的10个字符按由小到大的顺序排列。#define N 10#include #include void sort(char str[])( int i,j;char t;for (j=0;jfor (i=0;iif (str[i]>str[i+1]){t=str[i];str[i]=str[i+1];str[i+1]=t;)}void main ( )(char ch[N];int i,flag;for(i=0;i<10;i++)scanf("%c",&ch[i]);sort(ch);printf("string sorted:n");for (i=0;iprintf("%c",ch[i]);)8.12用牛顿迭代法求根。方程为 ,系数 的值依次为1,2,3,4。求x在1附近的一个实根。求出根后由主函数输出。[解析]牛顿迭代[10]公式:#include #include double f(float a,float b,float c,float d,double x)(return a*x*x*x+b*x*x+c*x+d;)double f1(float a,float b,float c,double x)(return 3*a*x*x+2*b*x+c;)double root(float a,float b,float c,float d,double x)(double x0;do{ x0=x;x=x0-f(a,b,c,d,x0)/f1(a,b,c,x0);)while(fabs(x-x0)>1e-5);return x;}void main()(float a, b, c, d;double x;a=1;b=2;c=3;d=4;x=1;x=root(a,b,c,d,x);printf (" root:%lfn",x);)8.13用递归方法求n阶勒让德多项式的值,递归公式为:#include "stdio.h"double P(double x, int n)( if(n==0) return 1;if(n==1) return x;if(n>1) return ((2*n-1)*x-P(x,n-1)-(n-1)*P(x,n-2))/n;)void main()( double x; int n;double P(double x, int n);scanf("%lf%d",&x, &n);printf("%lf", P(x, n)) ;)8.14输入10个学生5门课的成绩,分别用函数实现下列功能:(1)计算每个学生的平均分;(2)计算每门课的平均分;(3)找出所有50个分数中的最高的分数所对应的学生和课程;(4)求出平均分方差;其中, 为某一学生的平均分。
第8章 函数参考答案[知识要点]C语言的基本组成单位函数。C是由一个且仅有一个主函数( main)和若干个子函数组成.子函数可有可无。一个C语言
源程序[1]执行,从主函数开始,以主函数结束。C语言称为
函数式语言[2],即用户可根据解决问题的算法编成一个相对独立的函数模块,然后采用调用的方法来
使用函数[3]。采用了函数模块式的结构的特点:程序的层次结构清晰,便于程序的编写、阅读和
调试[4]。C语言提供了极为丰富的库函数,使用这些库函数时,在源程序的头部使用文件包含命令。如:数学函数 #include 字符函数 #include 字符串函数 #include 输入输出函数 #include 动态
存储分配[5]函数 #include #include 清屏函数 #include 日期和时间函数 #include 函数可以嵌套调用,而不可嵌套定义。函数的值: 函数的值的
数据类型[6]由函数定义时所决定的。调用函数时可有返回值和无返回值两种。有返回值的函数在函数体内必有一条或多条 return 语句,无返回值的函数定义为void类型,且在函数体无return 语句。
函数调用[7]时参数的传递:主调函数和被调函数之间数据传递有两种,数值传递和地址传递。[习题参考答案]8.1写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果,两个整数由键盘输入。[解析]用碾转相除法求最大公约数。最小公倍数=两个整数之积/最大公约数。#include int gcf(int x,int y) /*求两整数的最大公约数*/{int t,r;if (x{t=x;x=y;y=t;}while ((r=x%y)!=0){ x=y;y=r;}return y;}int lcm(int x,int y,int h) /*求两整数的最小公倍数*/{return(x*y/h);}void main ( ){ int a,b,df,sc; /* df:所求的最大公约数,sc:所求的最小公倍数*/printf("Input a,b\n");scanf(“%d%d”,&a,&b);df=gcf(a,b);printf(“G.C.F=%d\n”,df);sc=lcm(a,b,df);printf(“L.C.M=%d\n”,sc);}8.2 求方程ax2+bx+c=0的根,用3个函数分别求当b2-4ac大于0,等于0和小于0时的根,并输出结果。从主函数输入a,b,c的值。# include void real_root(float a,float b,float disc) /*求方程的两个不相同的实根*/{float x1,x2;x1=(-b+sqrt(disc))/(2*a);x2=(-b-sqrt(disc))/(2*a);printf("x1=%5.2f\tx2=%5.2f\n",x1,x2);}void equal_root(float a,float b) /*求方程的两个相同的实根*/{ float x1,x2;x1=x2=(-b)/(2*a);printf("x1=%5.2f\tx2=%5.2f\n",x1,x2);}void imaginary_root(float a,float b,float disc) /*求方程的两个不相同的虚根*/{ float p,q;p=-b/(2*a);q=sqrt(disc)/(2*a);printf("x1=%5.2f+%5.2fi\tx2=%5.2f-%5.2fi\n",p,q,p,q);}void main ( ){float a,b,c,disc;printf("\nInput a,b,c:\n");scanf("%f%f%f",&a,&b,&c);disc=b*b-4*a*c;if (disc>0)real_root(a,b,disc);else if (disc==0)equal_root(a,b);elseimaginary_root(a,b,disc);}8.3写一个判素数的函数,在主函数输入一个整数,输出是否素数的信息。[解析]:素数(质数):只能被1和该整数本身整除的数为素数。换句话说,只有两个正因数(1和自己)的自然数即为素数。#include int prime(int n){int flag=1,i; /*flag:标识变量*/for (i=2;i<=n/2 && flag==1;i++)if (n%i==0)flag=0;return flag ;}void main ( ){int n;printf("\nInput an integer:");scanf("%d",&n);if (prime(n))printf("\n %d is a prime.",n);elseprintf("\n %d is not a prime.",n);}[扩展]求100以内的所有的素数。#include int prime(int n){int flag=1,i; /*flag:标识变量*/for (i=2;i<=n/2 && flag==1;i++)if (n%i==0)flag=0;return flag ;}void main ( ){int a[100],i,j=0;for(i=2;i<=100;i++)a[i]=i;for(i=2;i<=100;i++)if (prime(a[i])){ if(j++%5==0) printf("\n"); /*控制每行输出的个数,每行按5个输出*/printf("%5d",a[i]);}}8.4写一函数,使给定的一个二维数组(3×3)转置,即行列互换。# define N 3#define M 3#include void fun (int a[N][M],int b[M][N]){ int i,j,t;for (i=0;ifor (j=0;jb[j][i]=a[i][j];}void main ( ){ int i,j,a[N][M],b[M][N];printf("Input %d * %d array:\n",N,M);for (i=0;ifor (j=0;jscanf("%d",&a[i][j]);printf("\Original array : \n");for (i=0;i{for (j=0;jprintf("%4d",a[i][j]);printf("\n");}fun(a,b);printf("Convert array:\n");for (i=0;i{for (j=0;jprintf("%4d",b[i][j]);printf("\n");}}[解析]字符串处理方法,一是字符数组,二是指针,编写函数时,采用地址传递。#include #include void inverse (char str[ ]){char t;int i,j;for (i=0,j=strlen(str)-1;i{ t=str[i];str[i]=str[j];str[j]=t;}}void main ( ){char str[80];void inverse (char str[ ]);printf(“Input string:”);gets(str);inverse(str);puts(str);}8.6写一函数,将两个字符串连接。[解析]:将串2连接在串1 的后面,形成一新串。新串末尾须加字符串结束标志。#include #include char connect(char str1[ ],char str2[ ]){int i,j;for (j=strlen(str1),i=0;str2[i]!='\0';i++)str1[i+j]=str2[i];str1[i+j]='\0'; /*新串末尾须加字符串结束标志\0*/}void main ( ){ char s1[80],s2[80];printf("\nInput string1:");gets(s1);printf("\nInput string2:");gets(s2);connect(s1,s2);puts(s1);} ng is %s\n”,s);}8.7 写一个函数,将一个字符串中的元音字母复制到另一个字符串,然后输出。#include #include void string_copy(char str[]){ int i,j=0;for(i=0;str[i]!='\0';i++)if(str[i]=='a'||str[i]=='e'||str[i]=='i'||str[i]=='o'||str[i]=='u')str[j++]=str[i];str[j]='\0';puts(str);}void main ( ){ char str[80];int n;gets(str);string_copy(str);}8.8写一函数,输入一个4位数字,要求输出这4个数字字符,但每两个数字之间有一个空格。如输入1990,应输出”1 9 9 0”。#include #include void change(int n,char str[]) /* 该函数的功能将数值转换为数字字符*/{ int i;for(i=3;i>=0;i--){ str[i]=n%10+'0';n/=10;}str[4]='\0';}void insert(char str[]) /* 该函数的功能插入空格并输出该数字字符*/{ int i;for (i=strlen(str);i>0;i--){ str[2*i]=str[i];str[2*i-1]=' ';scanf("%d,%d",&a,&n);printf("a=%d n=%d \n",a,n);while(count<=n){tn=tn+a;sn=sn+tn;a=a*10;++count;}printf("a+aa+aaa+…=%d\n",sn);}6.4 求 (即1+2!+3!+4!+…+20!)void main(){float n,s=0,t=1;for(n=1;n<=20;n++){t=t*n;s=s+t;}printf("1!+2!+…+20!=%e\n",s);}阶乘利用递归,再求和:#includeusing namespace std;long Func(int n){if(1==n)return n;if(n>1)return n*Func(n-1);}main(){long s=0;int i=1;while (i<=6){s=s+Func(i);i++;}cout<}6.5 求 。void main(){int k,N1=100,N2=50,N3=10;float s1=0.0,s2=0.0,s3=0.0;for(k=1;k<=N1;k++)/*计算1到100的和*/{s1=s1+k;}for(k=1;k<=N2;k++)/*计算1到50各数平方和*/{s2=s2+k*k;}for(k=1;k<=N3;k++) /*计算1到10各数倒数之和*/{s3=s3+1.0/k;}printf("总和=%8.2f\n",s1+s2+s3);}已通过int main(){int k=1,i=11,j=51;float s=0.0;while(k<=10){s=s+k+k*k+1.0/k;while(k==10 && i<=50){s=s+i+i*i;}puts(str);}void main ( ){ char str[80];int n;printf("\nInput number :");do /* 该循环控制输入的数为四位整数*/scanf("%d",&n);while(n<999||n>10000);change(n,str);insert(str);}8.9编写一函数,有
实参[8]传来一个字符串,统计此字符串中字母,数字,空格和其它字符的个数,在主函数中输入字符串以及输出上述的结果。#include #include #include int letter,digit,space,others; /* 说明定义为
全局变量[9],全局变量不赋值时自动赋0值 */int count(char str[ ]){int i;for (i=0;str[i]!='\0';i++)if (isalpha(str[i]))letter++;else if (isdigit(str[i]))digit++;else if (str[i]==' ')space++;elseothers++;}void main ( ){char str[80];printf("\nInput string:\n");gets(str);printf("string:");puts(str);count(str);printf("letter:%d,digit:%d,space:%d,others:%d\n",letter,digit,space,others);}8.10写一函数,输入一行字符,将此字符串中最长的单词输出。[解析]先确定单词是如何组成的。假若以空格、数字或其它字符作为单词的分隔。#include #include #include char string_long(char str[]){int i,j,k=1,flag=1,max=0,si=0,sj;for(i=0;str[i]!='\0';i++){ if(isalpha(str[i]))if(flag){ j=i;flag=0;}elsek++;else{if(max{ max=k;si=j; /* si :记长串的起始位置*/sj=si+k; /* sj :记长串的结束位置*/}flag=1;k=1;}}str[sj]='\0';puts(&str[si]);}void main ( ){ int i;char string[80];printf("Input one line character:\n");gets (string);printf("\nThe longest word is :");string_long(string);}8.11写一函数,用“起泡法”对输入的10个字符按由小到大的顺序排列。#define N 10#include #include void sort(char str[]){ int i,j;char t;for (j=0;jfor (i=0;iif (str[i]>str[i+1]){t=str[i];str[i]=str[i+1];str[i+1]=t;}}void main ( ){char ch[N];int i,flag;for(i=0;i<10;i++)scanf("%c",&ch[i]);sort(ch);printf("string sorted:\n");for (i=0;iprintf("%c",ch[i]);}8.12用牛顿迭代法求根。方程为 ,系数 的值依次为1,2,3,4。求x在1附近的一个实根。求出根后由主函数输出。[解析]牛顿
迭代[10]公式:#include #include double f(float a,float b,float c,float d,double x){return a*x*x*x+b*x*x+c*x+d;}double f1(float a,float b,float c,double x){return 3*a*x*x+2*b*x+c;}double root(float a,float b,float c,float d,double x){double x0;do{ x0=x;x=x0-f(a,b,c,d,x0)/f1(a,b,c,x0);}while(fabs(x-x0)>1e-5);return x;}void main(){float a, b, c, d;double x;a=1;b=2;c=3;d=4;x=1;x=root(a,b,c,d,x);printf (" root:%lf\n",x);}8.13用递归方法求n阶勒让德多项式的值,递归公式为:#include "stdio.h"double P(double x, int n){ if(n==0) return 1;if(n==1) return x;if(n>1) return ((2*n-1)*x-P(x,n-1)-(n-1)*P(x,n-2))/n;}void main(){ double x; int n;double P(double x, int n);scanf("%lf%d",&x, &n);printf("%lf", P(x, n)) ;}8.14输入10个学生5门课的成绩,分别用函数实现下列功能:(1)计算每个学生的平均分;(2)计算每门课的平均分;(3)找出所有50个分数中的最高的分数所对应的学生和课程;(4)求出平均分方差;其中, 为某一学生的平均分。