一、实验的目的
1、 掌握定义函数的方法。
2、 掌握函数的实参与形参的对应关系以及“值传递”的方式。
3、 掌握函数的嵌套调用及其递过调用的方法。
4、 掌握全局变量与局部变量的使用。
二、要求及内容
本实验主要完成函数的的应用训练,总共要求完成四个问题的源代码的编辑、编译、连接与运行,最终产生相关的运行结果,按规定要求提交相应的实验报告。具体要求完成的问题如下:
1、 编程求100—200之间的素数,该区间的数据从主函数中传出,由一个判别素数的函数进行判别后返回主函数输出。
2、 编写一个程序,由主函数传来一个字符串,在函数中分别统计出字母、数字、空格和其它字符的个数,在主函数中打印输出。
3、 用递归算法将一个整数n转换成相应的字符串。
4、 输入10个学生5门课的成绩,分别用函数实现下列各项功能:
(1)计算出每个学生的平均分;
(2)计算出每门课程的平均分;
(3)找出所有50个分数中最高分数所对应的学生和课程。
三、算法设计思想或程序流程图
1、根据素数是不能被2到本身的开平方之间的任何一个整数整除的整数,设计一个判别一个整数是不是素数的函数,即为“sushu”,然后在主函数中调用并求出100—200中的所有素数。
2、编写一个判断字母、数字、空格以及其他字符的函数,即“jisuan”,从主函数中输入一个字符串,调用函数对其计算相关字符的个数。
3、从主函数中输入一个n。设计函数“zfc”,如果n整除10为0,则输出其对应的ASCLL码,如果不为0,则继续返回函数“zfc”,即递归调用,直到为0为止。主函数中,判断n是否大于0,若不大于0,则输出时求出n的相反数并在其之前加一个“-”号。
4、设计一个“score”函数,结合for循环语句和数组计算每个学生和每门课程的平均分并且找出所有50个分数中最高分数所对应的学生和课程,然后再main函数中调用。
四、所使用的软硬件平台
软件平台:Microsoft Windows XP专业版SP3,Microsoft Visual C++ 6.0。
硬件平台:联想系列,Intel(R)Core(TM)i3,CPU 3.20Ghz,2.99GB内存,550GB硬盘。
五、源程序代码
1、#include<stdio.h>
#include<math.h>
int main()
{int t;
int sushu(int n);
for(t=100;t<=200;t++)
{if(sushu(t)==0)
printf("%5d",t);
};
printf("\n");
}
int sushu(int n)
{int i;
for(i=2;i<sqrt(n);i++)
if(n%i==0) break;
if(i>sqrt(n)) return 0;
}
2、#include<stdio.h>
int k,l,m,n;
int main()
{int jisuan(char a);
int i;
char zifuchuan[80];
printf("请输入一个字符串:\n");
gets(zifuchuan);
k=0,l=0,m=0,n=0;
for(i=0; zifuchuan [i]!='\0';i++)
jisuan(zifuchuan [i]);
printf("字母的个数是:%d,数字的个数是:%d,空格的个数是:%d,其他字符的个数是:%d\n",k,l,m,n);
}
int jisuan(char a)
{if((a>='a' && a<='z')||(a>='A' && a<='Z')) k++;
else if(a>='0' && a<'9') l++;
else if(a==' ') m++;
else n++;
return 0;
}
3、#include <stdio.h>
int main()
{
void zfc(int n);
int n;
printf("请输入一个整数n:");
scanf("%d",&n);
printf("相应的字符串为:");
if(n<0)
{
putchar('-');
n=-n;
}
zfc(n);
printf("\n");
}
void zfc(int n)
{
int m;
if((m=n/10)!=0) zfc(m);
putchar(n%10+'0');
}
4、#include<stdio.h>
#include<conio.h>
void score()
{int i,j,a[10][5],max=0,sum=0,b[2];
printf("请分别输入10个学生5门课的成绩:\n");
for(i=0;i<10;i++)
for(j=0;j<5;j++)
scanf("%d",&a[i][j]);
printf("每个学生的平均分:\n");
for(i=0;i<10;i++)
{for(j=0;j<5;j++)
{if(a[i][j]>max) max=a[i][j];
sum+=a[i][j];
}
printf(" NO.%d %d\n",i,sum/5);
sum=0;
}
printf("每门课程的平均分:\n");
for(j=0;j<5;j++)
{for(i=0;i<10;i++)
{sum+=a[i][j];
if(a[i][j]==max)
{b[0]=i; b[1]=j;}
}
printf("科目%d:%d\n",j,sum/10);
sum=0;
}
printf("最高分数所对应的学生:NO.%d,最高分数所对应的课程:科目%d",b[0],b[1]);
}
int main()
{void score();
getch();
printf("\n");
return 0;
}
六、运行结果及分析
1、
2、
3、
4、
七、结论与体会(在上机程序调试中遇到的问题、采用的解决办法、得到的收获)
通过与C函数的学习,让我体会到了函数的引入可以减少程序目标代码的简便性。不过函数的学习需要细心与耐心,其定义与调用的方法需要仔细斟酌。
函数分为库函数和用户定义函数,库函数是C系统提供的,可以直接调用,而用户定义函数则是用户自己设计的函数。函数的参数分为形参和实参两种,这两个概念容易混淆,需在不断上机的实践过程中仔细理解体会,形参出现在函数定义中,实参出现在函数调用中,进行函数调用时,实参的值将传送给形参。C语言中,允许函数的嵌套调用和函数的递归调用。C函数的使用一般经过声明、调用与定义三部曲。
仅供学习交流参考
第二篇:C语言实验四实验报告——函数
一、 实验项目名称
函数
二、 实验目的
1.掌握C函数的定义方法、函数的调用方法、参数说明以及返回值。掌握实参与形参的对应关系以及参数之间的“值传递”的方式;掌握函数的嵌套调用及递归调用的设计方法;
2.掌握全局变量和局部变量、动态变量与静态变量的概念和使用方法;
3.在编程过程中加深理解函数调用的程序设计思想。
三、实验内容
1.多模块的程序设计与调试的方法;
2.函数的定义和调用的方法;
3.用递归方法进行程序设计。
具体内容:
1.编写一个函数primeNum(int num),它的功能是判别一个数是否为素数。如果num是素数,返回该数;否则返回0值。
要求:
(1)在主函数输入一个整数num,调用该函数后,输出num是否是素数的信息。输出格式为:num is prime或num is not prime。
(2)分别输入以下数据:0,1,2,5,9,13,59,121,运行程序并检查结果是否正确。
2.编写函数computNum( int num),它的功能是计算任意输入的一个正整数的各位数字之和,结果由函数返回(例如:输入数据是123,返回值为6)。
要求: num由主函数输入,调用该函数后,在主函数内输出结果。
3.编写函数,mulNum(int a,int b),它的功能是用来确定a和b是否是整数倍的关系。如果a是b的整数倍,则函数返回值为1,否则函数返回值为0。
要求:
(1)在主函数中输入一对数据a和b,调用该函数后,输出结果并加以相应的说明。例如:在主函数中输入:10,5 ,则输出:10 is multiple of 5.
(2)分别输入下面几组数据进行函数的正确性测试:1与5、5与5、6与2、6与4、20与4、 37与9等,并对测试信息加以说明。
4.编写一个计算组合数的函数combinNum(int m,int n)。计算结果由函数返回。 计算组合数的公式是:
c(m,n)=m!/(n!*(m-n)!)
要求:
(1)从主函数输入m和n的值。对m>n、m<n和m=n 的情况作分别处理后调用函数combinNum(m,n),在主函数内输出结果值。
(2)对m>n、m<n和m=n 的情况各取一组数据进行测试,检查程序的正确性。
(3)修改程序,把两个函数分别放在两个程序文件中,作为两个文件进行编译、链接和运行。
5.整数a,b的最大公约数是指既能被a整除又能被b整除的最大整数。整数a,b的最小公倍数是指既是a的倍数又是b的倍数的最小整数。编写两个函数,一个函数gcd()的功能是求两个整数的最大公约数,另一个函数mul()的功能是求两个整数的最小公倍数。
要求:
(1)两个整数在主函数中输入,并在主函数中输出求得的最大公约数和最小公倍数。
(2)首先将两个整数a和b作为实参传递给函数gcd(),求出的最大公约数后,由函数gcd()带值返回主函数,然后将最大公约数与两个整数a、b一起作为实参传递给函数mul(),以此求出最小公倍数,再由函数mul()带值返回主函数。
(3)修改函数gcd(),函数gcd()采用递归调用的编写方法,两个整数a和b的最大公约数的递归公式是:
如果b=0,那么gcd(a,b)=x,否则gcd(a,b)= gcd(b,a%b)。 然后将最大公约数与两个整数a、b一起传递给函数mul(),求出最小公倍数,再由函数mul()将最小公倍数返回主函数。
(4)修改程序,采用全局变量的处理方法,将最大公约数和最小公倍数都设为全局变量,分别用函数gcd()和函数mul()求最大公约数和最小公倍数,但其值不是由函数返回,而是通过全局变量在函数之间传递的特性将结果反映在主函数中。
四、实验步骤及结果
打开编程软件,分别写入以下代码:
一、
#include<stdio.h>
int PrimeNum(int num);/*声明判断函数*/
void main()
{
int i,num;
printf("Please input num: ");
scanf("%d",&num);
i=PrimeNum(num);/*调用判断函数*/
if (i==0)
printf("%d is not prime",num);
else
printf("%d is prime",num);
}
int PrimeNum(int num)
{
int n,m;
if (num==1)/*1不是素数*/
m=0;
} else{ for (n=2;n<num;++n) if (num%n==0) break;/*若能被整除,说明不是素数,停止循环*/ if (n>=num) m=num; else m=0;} return (m);/*返回m*/
二、
#include <stdio.h>
int computNum(int num);/*声明函数*/ void main()
{
int num,n;
printf("请输入不多于10位的整数:"); scanf("%d",&num);
n=computNum(num);/*调用函数*/ printf("%d",n);
}
int computNum(int num)
{
int n,j;
n=1;j=0;
for (n=1;n<11;++n)
} { j=j+num%10;/*将数的每一位数加到j上*/ num=num/10; } return j;/*直接返回j*/
三、
#include<stdio.h>
int mulNum(int a,int b);/*声明函数*/
void main()
{
int a,b,c;
printf("Please input a and b:\n");
scanf("%d,%d",&a,&b);
c=mulNum(a,b);/*调用函数*/
if (b>a)/*大的数是小的数的倍数,所以要判断两个数的大小*/ {
c=b;
b=a;
a=c;
}
if (c==1)/*两数是倍数关系*/
printf("%d is multiple of %d",a,b);
else/*不成倍数关系*/
printf("%d is not multiple of %d",a,b);
}
int mulNum(int a,int b)
{
int c;
if (a%b==0 || b%a==0)/*判断是否能被整除*/
c=1;
else
c=0;
return c;
}
四、
#include <stdio.h>
int combinNum(int m,int n);/*声明函数*/
void main()
{
int m,n,c;
printf("Please input m and n: ");
scanf("%d,%d",&m,&n);/*输入两个数*/
if (m<n || m<0 || n<0)/*判断输入的两个数是否符合数学要求*/
printf("Math error!\n\"m\" cannot smaller than \"n\"!\n\"m\" or \"n\" can`t smaller than 0!");
else
{
c=combinNum(m,n);/*调用函数*/
printf("c(m,n)=m!/(n!*(m-n)!)=%d",c);
}
}
int combinNum(int m,int n)
{
int accmulNum(int m);/*声明阶乘函数*/
int i,j,k,h;
i=accmulNum(m);/*调用阶乘函数*/
j=accmulNum(n);
k=accmulNum(m-n);
h=i/(j*k);
return h;
}
int accmulNum(int m)/*求数的阶乘的函数*/
{
} int i,j; j=1; for (i=1;i<=m;++i) j=j*i; return j;
修改方案:
在文件目录下创建头文件user.h,头文件内有如下内容:
int combinNum(int a,int b);
int accmulNum(int a);
在主程序预处理中加入#include”use.h”,将主程序保存为main.cpp,被调用程序保存为user.cpp,在命令提示符中先后输入cl user.cpp /c、cl main.cpp /c、link main.obj user.obj,得到程序main.exe。
五
#include <stdio.h>
int gcd(int a,int b);/*声明求公约数函数*/
int mul(int a,int b);/*声明公倍数函数*/
void main()
{
int a,b,c,d;
printf("请输入a,b:\n");
scanf("%d,%d",&a,&b);
c=gcd(a,b);/*调用公约数函数*/
d=mul(a,b);/*调用公倍数函数*/
printf("最大公约数是:%d,最小公倍数是:%d",c,d);
}
int gcd(int a,int b)/*公约数函数*/
{
int i,j,k;
j= (a>b)? b:a;
for (i=j;i>=1;--i)
{
if (a%i==0 && b%i==0)
{
k=i;break;/*第一次出现能同时被ab整除的是最小公约数*/ }
}
return k;
}
int mul(int a,int b)
{
int gcd(int a,int b);/*调用公约数函数*/
int h,k;
k=gcd(a,b);
h=a*b/k;/*公约数和公倍数的数学关系*/
return h;
}
使用递归调用修改方案:
将函数int gcd(int a,int b)的定义改为:
int gcd(int a,int b)
{
int c,i;
for (;b!=0;)
{
i=a;
a=b;
b=i%b;
c=gcd(a,b);
}
if(b==0)
c=a;
return c;
}
采用全局变量修改方案
#include <stdio.h>
int k=0,h=0;
int gcd(int a,int b);
int mul(int a,int b);
void main()
{
int a,b,c,d;
scanf("%d,%d",&a,&b);
gcd(a,b);
mul(a,b);
printf("最大公约数是:%d,最小公倍数是:%d",k,h); }
int gcd(int a,int b)
{
int i,j;
j= (a>b)? b:a;
for (i=j;i>=1;--i)
{
if (a%i==0 && b%i==0)
{
k=i;break;
}
}
return k;
}
int mul(int a,int b)
{
int gcd(int a,int b);
k=gcd(a,b);
h=a*b/k;
return h;
}
五、思考题或实验感想
1.小结函数的定义及调用方法;
答:函数的定义的一般形式为:
类型标识符 函数名 (形式参数表列)
{
声明部分
语句部分
}
函数的调用很灵活,可以由主函数点用其他函数,其他函数也可以互相调用,要调用函数必须要先声明“类型标识符 函数名 ();”然后才能调用。
2.小结函数中形参和实参的结合规则;
答:(1)、在定义函数中指定的形参,在未出现函数调用时,它们不占内存中的存储单元。(2)、实参可以是常量、变量或表达式,在调用时将实参的值赋给形参。(3)、在被定义的函数中,必须指定形参的类型。(4)、实参和形参和类型应相同或赋值兼容。(5)、在C语言中,实参向形参的数据传递是“值传递”,单向传递,只由实参传给形参,而不能由形参传回来给实参。
3.编写和调试包含多模块的程序时,容易出现什么样的错误?根据自己的实践总结一下。
答:容易出现变量的重定义,被定义函数中有未声明的标识符,函数返回值的类型和函数类型不对应,几个函数互相调用时未声明。