C语言程序设计实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验报告一
学生姓名:学号:专业班级:
实验类型:■验证□综合□设计□创新实验日期:2011年03月09日实验成绩:
一、实验项目名称
C语言的编程环境
二、实验目的
1.初步了解C程序的编译、连接和运行的过程。
2.掌握和理解C程序的结构。
三、实验内容
1.使用Visual c++6.0
2.运行一个简单的C程序
四、实验环境
PC微机;
Windows 操作系统;
Visual C++ 程序集成环境。
五、实验步骤
1.启动Turbo C
2.输入程序
输入以下程序
main()
{
printf(“How are you!”);
}
3.运行程序
4
4.保存文件
5.退出TC程序
6.打开已经存在的文件
六、思考题
总结实验中在编辑、编译、运行等各环节中所出现的问题及解决方法。
实验报告二
学生姓名:学号:专业班级:
实验类型:■验证□综合□设计□创新实验日期:2011年03月21日实验成绩:
一、实验项目名称
数据的输入与输出
二、实验目的
1.熟练掌握字符数据的输入与输出函数getchar和putchar的使用
2.熟练掌握格式输入输出函数scanf和printf的使用
3.进一步实习C程序的编辑环境
三.实验内容
4.4 若a=3,b=4,C=5,x=1.2,y=2.4,z=-3.6,u=51274,n=128765,cl='a',c2='b',想得到以下输出结果
,你写出程序。
要求输出的结果如下:
a= 3 b= 4 c= 5
x=1.200000,y=2.400000,z=-3.600000
x+y= 3.60 y+z=-1.20 z+x=-2.40
u= 51274 n= 128765
c1='a' or 97(ASCII)
c2='B' or 98(ASCII)
源程序:
#include<stdio.h>
main()
{
int a=3,b=4,c=5;
long int u=51274,n=128765;
float x=1.2,y=2.4,z=-3.6;
char c1='a',c2='b';
printf ("a=%2d b=%2d c=%2d\n",a,b,c);
printf ("x=%f,y=%f,z=%f\n",x,y,z);
printf ("x+y=%5.2f y+z=%5.2f z+x=%5.2f\n",x+y,y+z,z+x);
printf ("u=%6ld n=%9ld\n",u,n);
printf ("%s%s%d%s\n","c1='a'","or",c1,"(ASCII)");
printf ("%s%s%d%s\n","c2='B'","or",c2,"(ASCII)");
}
运行结果如下:
四、实验环境
PC微机,Windows 操作系统,Visual c++ 程序集成环境
五、实验步骤
步骤1、编写程序用printf函数来求得实验内容中表达式的结果步骤2、按要求完成实验内容4.4
步骤3、参照实验一的报告书写规范,完成此次实验报告的编写六、实验小结
对实验不够熟悉要多加练习才是!
实验报告三
学生姓名:学号:专业班级:
实验类型:■验证□综合□设计□创新实验日期:2011年03月28日实验成绩:
一、实验项目名称
数据类型、运算符和表达式
二、实验目的
1.了解C语言中数据类型的意义;
2.掌握不同数据类型之间的赋值的规律;
3.学会有关C语言的有关运算符,以及包含这些运算符的表达式,特别是是++和—运算符的使用。
4.进一步熟悉C程序的编辑环境。
三.实验内容
4.8 设圆的半径R=1.5,圆柱高h=3,求圆周长,圆面积,圆球表面积,圆球体积,圆柱体积。
用scanf输入数据,输出结果,请编出程序。
源程序#include<stdio.h>
void main()
{float r,h,C1,Sa,Sb,Va,Vb;
scanf("%f,%f",&r,&h);
C1=2*3.14*r;
Sa=3.14*r*r;
Sb=4*Sa;
Va=4/3*3.14*r*r*r;
Vb=Sa*h;
printf ("C1=%.2f\n",C1);
printf ("Sa=%.2f\nSb=%.2f\nVa=%.2f\n",Sa,Sb,Va);
printf ("Vb=%.2f\n",Vb); }
输出结果如下:
4.9 输入一个华氏温度,要求输出摄氏温度。
公式C=5/9(F-32).
源程序:
#include<stdio.h>
void main()
{
float c,F;
scanf ("%f",&F);
c=5.0/9*(F-32);
printf("摄氏温度是:c=%.2f\n",c);
}
运行结果如下:
四、实验环境
PC微机,Windows 操作系统,Visual c++ 程序集成环境
五、实验步骤
步骤1、编写程序用printf函数来求得实验内容1、2中表达式的结果步骤2、按要求完成实验内容4.8、4.9
步骤3、参照实验一的报告书写规范,完成此次实验报告的编写
实验报告四
学生姓名:学号:专业班级:
实验类型:■验证□综合□设计□创新实验日期:2011年04月11日实验成绩:
一、实验项目名称
控制语句的使用和熟悉
二、实验目的
1.熟练掌握if 、if…else、if…elseif语句和switch语句格式及使用方法,掌握if语句中的嵌套关系和匹配原则,利用if语句和switch语句实现分支选择结构。
2.熟练掌握while语句、do ...while语句和for语句格式及使用方法,掌握三种循环控制语句的循环过程以及循环结构的嵌套,利用循环语句实现循环结构。
3.掌握简单、常用的算法,并在编程过程中体验各种算法的编程技巧。
进一步学习调试程序,掌握语法错误和逻辑错误的检查方法。
三、实验内容和步骤及结果
1.选择结构程序设计;
2.if语句的使用;
3.使用switch语句实现多分支选择结构;
4.三种循环语句的应用;
5.循环结构的嵌套;
6.break和continue语句的使用。
具体内容:
一、编程实现:输入一个整数,将其数值按照①小于10,②10~99,③100~999,④1000以上四个类别分类并显示。
要求:
(1)将变量定义为整型。
(2)输入整数前,利用puts()/printf()给出提示信息。
(3)输出结果时要有必要的说明,例如:输入358时,显示358 is 100 to 999。
(4)该程序利用if语句实现。
源程序:
#include <stdio.h>
void main()
{
int a,b;
printf("Please input a number: ");
scanf("%d",&a);
if (a<10)
printf("%d is smaller than 10\n",a);
else if (a<=99)
printf("%d is 10 to 99\n",a);
else if (a<=999)
printf("%d is 100 to 999\n",a);
else
printf("%d is equal to or bigger than 1000",a);
}
运行结果如下:
二、编写程序:根据公式
2
2
2
2
21
3
1
2
1
1
1
6n
+
+
+
+
=
π
,输出π的值。
要求:
(1)变量π为单精度类型,n为整型;
(2)计算当n的取值分别为20,50 ,100,200时的π值,说明什么问题?
(3)修改程序,不给出n值,而改为求π值,直到最后一项的数值小于10-4为止。
(4)对修改后的程序,输出π值以及总的项数n。
输出格式为:π=值;n=值。
源程序:
(1)#include <stdio.h>
#include <math.h>
void main()
{
int n,j;
float p,k;
p=0;
printf("Please input n: ");
scanf("%d",&j);
n=1;
while (n<=j){
k=n*n;
p=p+1/k;
n=n+1;}
p=sqrt(6*p);
printf("pi = %f",p);
}
运行结果如下:
说明n越大pi的值越精确。
(2)修改后:
#include <stdio.h>
#include <math.h>
void main()
{
int n,j;
float p,k;
p=0;
n=0;
j=10000;
while ((n*n)<=j){
n=n+1;
k=n*n;
p=p+1/k;}
p=sqrt(6*p);
printf("π= %f,n=%d",p,n);
}
运行结果如下:
三、从键盘输入一个0~1000之间的任意整数,输出该整数的所有因子(例如:输入12,其因子为1,2,3,4,6,12)。
要求:
(1)采用while循环语句实现。
(2)输出格式为:Input:12
Output:1,2,3,4,6,12 。
源代码:
#include <stdio.h>
void main()
{
int n,j,k;
printf("input: ");
scanf("%d",&n);
if (n>0 && n<=1000)
printf("output: ");
else
printf("Error!Please input a number between 0 to 1000");
j=1;
while (j<=n)
{
if (n%j==0)
printf("%d ",j);
++j;
}
}
运行结果如下:
四、编程实现:由用户从键盘输入一串字符(以回车键结束),统计其中数字、大、小写字母、空格、其它字符的个数。
要求:
(1)通过键盘输入字符。
(2)给出相应的输入/输出信息提示。
并按照数字、大写字母、小写字母、空格、其它字符数的顺序输出结果。
源代码:
#include <stdio.h>
void main()
{
int i,n=0,j=0,k=0,s=0,e=0;
char c;
for (i=1;(c=getchar())!='\n';i=i+c)
{
if (c<=90 && c>=65)
j=j+1;
else if (c<=122 && c>=97)
k=k+1;
else if (c>=48 && c<=57)
n=n+1;
else if (c==32)
s=s+1;
else
e=e+1;
}
printf("字符串中含有%d个大写字母,%d个小写字母,%d个数字,%d个空格,%d 个其他符号",j,k,n,s,e);
}
运行结果如下:
五、计算并输出1000以内最大的10个素数以及它们的和。
要求:
(1)在程序内部加必要的注释。
(2)由于偶数不是素数,可以不考虑对偶数的处理。
(3)虽然在1000以内的素数超过10个,但是要对1000以内不够10个素数的情况进行处理。
(4)输出形式为:素数1+素数2+素数+…+素数10=总和值。
源代码为:
#include <stdio.h>
#include <math.h>
void main()
{
int a[10];
int i,j,s,n;
j=0;s=0;
for (n=999;n>=3;--n)/*对数进行从大到小循环,方便得到最大的十个素数*/
{
for(i=2;i<n;++i)
if(n%i==0)
break;/*若能被和本身之外的数整除,说明不是素数,结束循环*/ if (i>=n)/*若不被任何数整除,说明该数是素数*/{
j=j+1;/*累加计算素数的个数*/
if (j<=10)
a[j-1]=n;/*将前十个最大素数的值赋给数组a*/}
}
if (j<10)/*对以内素数不超过个的情况进行处理*/
{
printf("1000以内素数小于个,分别为:\n");
for (i=0;i<j;++i)
printf("%d ",a[i]);
}
else
{
printf("1000以内十个最大素数的和为:\n");
for (i=0;i<10;++i)
s=s+a[i];
for (i=0;i<9;++i)
printf("%d+",a[i]);
printf("%d=%d",a[9],s);/*以“素数+素数+……+素数=和”的形式输出是个最大素数以及它们的和*/
}
}
五、思考讨论题或体会或对改进实验的建议
1.对于多分支选择结构何时使用if语句的嵌套,何时使用switch语句?
答:if内嵌一般形式如下
if ( )
if ( ) 语句1
else 语句2
else
if ( ) 语句3
else 语句4
在分支较多且用if语句处理很繁杂的情况下可使用switch语句,如学生成绩分类、人口统计分类等。
2.小结三种形式的循环使用的区别。
答:(1)、几种循环可以用来处理同一个问题,一般情况下可以互相代替,但是一般不提倡用goto循环。
(2)、while循环中要在循环体内包含使循环趋于结束的语句(如++i或i=i+1等),for语句中的表达式3就是使循环趋于结束的语句,所以for语句比while功能更强,凡是while能完成的,for 语句都能实现。
(3)、在while语句中,循环变量初始化的操作应在while语句之前完成,而for语句可以再表达式1实现循环变量的初始化。
(4)、while循环和for循环可以用break语句跳出循环,用continue结束语句本次循环。
而对用goto语句和if语句构成的循环,不能使用break语句和continue语句进行控制。
实验报告五
学生姓名:学号:专业班级:
实验类型:■验证□综合□设计□创新实验日期:2011年04月18日实验成绩:
一、实验项目名称
数组
二、实验目的
1.掌握数组的基本概念,包括:数组的定义、数组的类型、数组的初始化、数组的赋值、数组元素下标的范围、数组元素的正确以及引用数组元素的输入/输出。
2.掌握字符数组与字符串的使用方法。
理解字符数组与其它数组的区别、理解字符串及其特点。
掌握常用的字符串处理库函数的用法并清楚对字符串的简单处理。
3.掌握与数组相关的算法,包括排序算法和查找算法等。
三、实验内容和步骤及结果
进行有关数组的程序设计。
具体内容:
1.编程实现:对任意一个一维数组,从中找出数组元素的最大值和最小值。
要求:
(1)数组为整型数组(10个元素)。
(2)使用scanf函数实现数组元素的输入。
在输入前给出必要的提示。
(3)输出时给出必要的说明,首先输出原始的10个元素,换行后输出最大值以及最大值在数组中的位置、最小值以及最小值在数组中的位置。
(4)如果现改为20个元素的数组,怎样修改程序?修改程序后,运行程序进行检查。
如果需要数组元素不断改变,应怎样修改程序?
在编程软件中写如以下代码:
#include <stdio.h>
void main()
{
int a[10],i,j,k,max,min;
printf("请输入10个数:\n");
for (i=0;i<10;++i)
scanf("%d",&a[i]);
printf("原始数据:");
for (i=0;i<10;++i)
printf("%d ",a[i]);
printf("\n");
max=a[0];/*初始化max和min*/
min=a[0];
for (i=0;i<10;++i)
{
if (a[i]>=max)
max=a[i];
if (a[i]<=min)
min=a[i];/*找最大值和最小值*/
}
printf("最大值为");
for (i=0;i<10;++i)/*应对有多个最值的情况*/
if (a[i]==max)
printf("第%d个",i+1);
printf("数,%d\n",max);
printf("最小值为");
for (i=0;i<10;++i)
if (a[i]==min)
printf("第%d个",i+1);
printf("数,%d",min);
}
修改为20个元素的方案:
将程序中所有的10改为20即可。
如果数组元素不断改变,只需将代码中的10改成元素个数即可。
运行结果:
2.编程实现:在给定的字符串中查找满足条件的第一个字符。
要求:
(1)字符串采用初始化的方式处理。
(2)通过scanf函数读入一个任意字符。
(3)在字符串中查找该字符,如果存在该字符,输出该字符在字符串中的位置以及相应的说明。
如果不存在该字符,则要给出相应的信息。
在编程软件中写如以下代码:
#include <stdio.h>
#include <string.h>
void main()
{
int j,n;
char i;
char c[]={"I am a student"};/*初始化字符串*/
printf("给定字符串为:%s\n请输入要查找的字符:",c);
scanf("%c",&i);
n=strlen(c);/*得到函数给定字符串的长度*/
for (j=0;j<n;++j)
if ((int)c[j]==(int)i)
{
printf("字符串中满足条件的第一个字符为第%d个字符",j+1);break;/*找到符合条件的第一个字符,结束循环*/
}
if (j>=n)
printf("字符串中不存在满足条件的字符!");
}
运行结果如下:
3.编程实现:首先任意输入一个大于2且小于10的整数n,再输入一个由n决定的二维整型数组(n ⨯n),形成n ⨯n阶矩阵,将矩阵中最大元素所在的行和最小元素所在的行对调后,再输出该矩阵(注意:数组不允许动态定义)。
例如:原始数据:n=4 结果数据:
1 2 3 4 8 11 14 16
3 5 9 10 3 5 9 10
8 11 14 16 1 2 3 4
15 2 7 6 15 2 7 6
要求:
(1)本题中所涉及到的循环都采用for语句。
(2)在输入/输出时进行必要的说明。
(3)对输入的2~10之间的整数(例如4)以n=4的格式输出。
(4)输入一个n ⨯n矩阵(假定最大值与最小值不在同一行上),输出原始矩阵数据(按上述矩阵形式)。
(5)查找最大值与最小值,将矩阵中最大元素所在的行和最小元素所在的行对调,输出对调后的
矩阵数据。
(6)修改程序,对最大值与最小值可能出现在一行上的情况做出说明。
(7)对n为3,4,5时,输入数组元素是要注意哪些问题?执行程序,检查程序的正确性。
源代码:
#include <stdio.h>
void main()
{
int n,j,k,z,x,max,min,a[10][10];
printf("请输入一个2到10之间的数:");
scanf("%d",&n);
printf("请输入一个n*n数组:\n");
for (j=0;j<n;++j)
for (k=0;k<n;++k)
scanf("%d",&a[j][k]);
printf("原始数组为:n=%d\n",n);
for (j=0;j<n;++j){
for (k=0;k<n;++k)
printf("%5d",a[j][k]);/*输出原始数组*/
printf("\n");/*输出n个数后换行,使数组为n*n的格式*/} max=a[0][0];/*初始化最大值和最小值*/
min=a[0][0];
z=0;x=0;
for (j=0;j<n;++j)
for (k=0;k<n;++k)
if (a[j][k]>max)
{
max=a[j][k];
z=j;/*得到最大值的行数*/
}
for (j=0;j<n;++j)
for (k=0;k<n;++k)
if (a[j][k]<min)
{
min=a[j][k];
x=j;/*得到最小值的行数*/
}
for (j=0;j<n;++j){
k=a[z][j];
a[z][j]=a[x][j];
a[x][j]=k;/*交换最大值所在行和最小值所在行*/} printf("结果数据:\n");
for (j=0;j<n;++j)/*输出结果*/{
for (k=0;k<n;++k)
printf("%5d",a[j][k]);
printf("\n");}
}
运行结果如下:
修改程序得到最大值和最小值所在行,只需在程序末尾加上语句:
printf(“最大值在第%d行,最小值在第%d行”,z,x);
在输入数组元素时要注意尽量不要重复出现最大值和最小值,程序会以最值中第一个出现的值作为最值。
4.编程实现“折半查找”的过程。
折半查找的处理过程是:在一个数据已排好序的数组中,首先比较关键字与数组中间的元素,如果两者相等,则查找结束;如果前者比后者小,则要查找的数据必然在数组的前半部,此后只需在数组的前半部中继续折半查找;如果前者的数值比后者大,则要查找的数据必然在数组的后半部,此后只需在数组的后半部继续进行折半查找。
要求:
(1)设定一个数组存放20个数据,用赋初值的方法在程序中给出(假设这些数据已排序)。
(2)用scanf函数输入一个要找的数。
(3)对查找的结果给出相应的说明,如果找到该数,则给出该数是数组中第几个元素。
如果该数不在数组中,则输出“无此数”信息。
(4)任意输入一些数据,检查程序的正确性。
(5)修改程序,设定输入的数据是无序的,采用scanf函数的形式输入,首先要对这些无序的数据进行排序,然后再采用“折半查找”。
最后通过测试几组差别较大的数据检查程序的正确性。
(6)修改程序,改为函数调用的形式。
编写一个选择法排序函数,对无序数据进行排序;编写一个查找函数对已排好序的数据进行查找。
在主函数中输入数据(无序),调用上述函数,输出结果。
程序:#include<stdio.h>
void main()
{
int a[20]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19},i;
int b,ture=0;
printf("please input the number:");
scanf("%d",&b);
if(a[10]==b)
printf("存在该数,位于第11个\n");
else
{
if(a[10]>b)
{
for(i=9;i>=0;i--)
if(a[i]==b)
{
ture=1;
printf("存在该数,位于第%d个\n",i+1);break;
}
}
else
{
for(i=11;i<20;i++)
if(a[i]==b)
{
ture=1;
printf("存在该数,位于第%d个\n",i+1);break;
}
}
}
if(ture==0)
printf("不存在该数\n");
}
运行结果如下:
5.编程实现:三个学生、五门课程的成绩分别存放在4×6矩阵的前3×5列,计算出每个学生的平均成绩存放在该数组的最后一列的对应行上。
计算单科的成绩总和存放在最后一行的对应列上,并输出单科成绩的平均分。
输入/输出格式举例如下:
Input(输入成绩):
65 87 68 56 78<cr>
83 94 67 85 91<cr>
71 75 69 84 89<cr>
Output(输出结果):
65 87 68 56 78 70.5
83 94 67 85 91 84.0
71 75 69 84 89 77.5
219.0 256.0 204.0 258.0 232.0 0
average:
73.0 85.3 68.0 86.0 77.3
要求:
(1)数组类型为实型,输入成绩由scanf函数实现。
(2)输出已输入的原始成绩数据(3×5)。
(3)计算每个学生的平均成绩以及单科的成绩总和并按要求填入到数组中,输出填入结果后的数组(4×6)。
(4)j计算单科平均成绩后输出。
源代码:
#include <stdio.h>
void main()
{
int j,k;
float a[3][5],d[3]={0},b[6]={0},c[5]={0};
printf("Input(输入成绩):\n");
for (j=0;j<3;++j)
for (k=0;k<5;++k)
scanf("%f",&a[j][k]);
for (j=0;j<3;++j)
for (k=0;k<5;++k)
d[j]=d[j]+a[j][k]/5;
for (k=0;k<5;++k)
for (j=0;j<3;++j)
b[k]=b[k]+a[j][k];
for (j=0;j<3;++j)
b[5]=b[5]+d[j];
for (k=0;k<5;++k)
c[k]=b[k]/3;
printf("\nOutput(输出结果):");
for (j=0;j<3;++j){
printf("\n ");
for (k=0;k<5;++k)
printf("%-7.0f",a[j][k]);
printf("%-7.1f",d[j]);}
printf("\n ");
for (k=0;k<6;++k)
printf("%-7.1f",b[k]);
printf("\nAverage:\n ");
for (k=0;k<5;++k)
printf("%-7.1f",c[k]);
}
运行结果如下:
6.编写函数catStr(char str1[],char str2[])用于进行两个字符串的连接,编写函数lenStr()用于统计一个字符串的长度。
编写函数cmpStr()用于判断两个字符串的大小。
要求:
(1)不允许使用字符处理库函数。
(2)在主函数以初始化的方式输入两个字符串str1、str2。
调用函数lenStr()计算字符串的长度。
(3)调用函数cmpStr()判断两个字符串的大小,如果str1大于等于str2,调用函数catStr()进行两个字符串的连接,将str1连接在str2后,否则,将str2连接在str1后,调用函数lenStr()统计连接后的字符串长度。
(4)在主函数中输出两个原始字符串和各自的长度以及处理后字符串及其长度。
#include <stdio.h>
void catStr(char str1[],char str2[]);/*声明连接两个字符串的函数*/
int lenStr(char str[]);/*声明统计长度的函数*/
int cmpStr(char str1[],char str2[]);/*声明比较字符串大小的函数*/
char str3[]={""};
void main()
{
int n,j,k,len1,len2,len3;
char c,str1[]={""},str2[]={""};
printf("请输入str1:");
gets(str1);
printf("请输入str2:");
gets(str2);
printf("str1原长为:%d\nstr2原长为:%d\n",lenStr(str1),lenStr(str2));/*调用统计长度的函数并输出原始长度*/
j=cmpStr(str1,str2);/*调用比较大小函数*/
if (j==1)/*将小字符串连接在大字符串后面*/{
printf("\"%s\"大于\"%s\"\n",str1,str2);
catStr(str1,str2);/*调用连接两个字符串的函数*/
printf("合成的字符串为:%s\n",str3);}
else{
printf("\"%s\"小于\"%s\"\n",str1,str2);
catStr(str2,str1);
printf("合成的字符串为:%s\n",str3);}
printf("合成的字符串长度为:%d",lenStr(str3));/*输出合成字符串的长度*/
}
int lenStr(char str[])/*统计字符串大小的函数*/
{
int n,j,k;
for (n=0;;++n)
if (str[n]=='\0'){
return n;
break;}
}
int cmpStr(char str1[],char str2[])/*比较字符串大小的函数*/
{
int n;
for (n=0;str1[n]!='\0' && str2[n]!='\0';++n){
if ((int)str1[n]>(int)str2[n]){
return 1;
break;}
if ((int)str1[n]<(int)str2[n]){
return 0;
break;}}
return 1;
}
void catStr(char str1[],char str2[])/*将str2连在str1后面,将得到的新字符串存入str3*/
{
int n,j;
int lenStr(char str[]);
for (n=0;n<lenStr(str1);++n)
str3[n]=str1[n];
for (n=0;n<lenStr(str2);++n)
str3[n+lenStr(str1)]=str2[n];
str3[lenStr(str1)+lenStr(str2)]='\0';/*结束字符串str3*/
}
运行结果:
有错!
四、思考题或实验感想
小结有关数组和字符串的程序设计方法:
首先要定义数组,必要时进行初始化。
然后要善于使用字符库函数,注意使用函数时不要重定义。
要注意数组的第一个下标是0。
数组和字符串的输入输出要善于利用for循环。
使用字符串库函数时要记得预处理。
实验报告六
学生姓名:学号:专业班级:
实验类型:■验证□综合□设计□创新实验日期:2011年05月09日实验成绩:
一、实验项目名称
函数
二、实验目的
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,运行程序并检查结果是否正确。
源代码:
#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*/
}
运行结果如下:
2.编写函数computNum( int num),它的功能是计算任意输入的一个正整数的各位数字之和,结果由函数返回(例如:输入数据是123,返回值为6)。
要求:num由主函数输入,调用该函数后,在主函数内输出结果。
源代码:
#include <stdio.h>
int computNum(int num);/*声明函数*/
void main()
{
int num,n;
printf("请输入不多于10位的整数:");
scanf("%d",&num);
n=computNum(num);/*调用函数*/
printf("%d\n",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*/
}
运行结果如下:
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等,并对测试信息加以说明。
源代码:
#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;
}
运行结果如下:
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)修改程序,把两个函数分别放在两个程序文件中,作为两个文件进行编译、链接和运行。
源代码:
#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。
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 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.编写和调试包含多模块的程序时,容易出现什么样的错误?根据自己的实践总结一下。
答:容易出现变量的重定义,被定义函数中有未声明的标识符,函数返回值的类型和函数类型不对应,几个函数互相调用时未声明。