实验一最简单的C程序设计
一、实验目的
1. 掌握C语言中使用最多的一种语句——赋值语句的使用方法。
2. 掌握各种类型数据的输入输出的方法,能正确使用各种格式转换符。
二、实验的内容和步骤
1.以下程序多处有错。要按下面指定的形式输入数据和输出数据时,请对该程序做相应的修改。
#include
void main ( )
{ double a,b,c,s,v;
printf(input a,b,c:\n);
scanf("%d%d%d",a,b,c);
s=a*b;
v=a*b*c;
printf("%d %d %d",a,b,c);
printf("s=%f\n",s,"v=%d\n",v);
}
当程序执行时,屏幕的显示和要求输入形式如下:
input a,b,c:1.0 2.0 3.0 →此处的1.0 2.0 3.0是用户输入的数据
a=1.000000 b=2.000000,c=3.000000 →此处是要求的输出格式
s=2.000000,v=6.000000
相关知识:①检查程序错误时应注意几点:
a)有时程序中一个错误会引发一系列错误信息,工作中不应被这种情况所迷惑,改正了一些错误后应及时对源程序重新进行编译;
b)如果修改错误时增删了行,或是一个行里有多个错误,更正前面错误时增删了字符,就可能导致系统对错误定位不准,此时应该重新编译;
c)系统给出的警告信息一般都说明程序中有问题,因为系统发现了可疑情况。对于警告信息同样要逐个仔细分析。除非明确认定不是问题,否则绝不能简单地认为不是错误而不予理睬。实际上,很多警告都是因为程序中确实有严重的隐含错误。
d) 在连接中发现新错误也需要仔细检查和修改程序。连接时发现的错误一般是由于函数名或外部变量名字写错,或者一些函数、外部变量没有定义引起的。系统不能对连接错误给以自动定位,只能提供有关的名字信息等。对于这类问题,可以借助编辑器的字符串查找命令进行定位。
②正确调用scanf函数和printf函数构成输入和输出语句。
2.有以下程序
#include
void main()
{ char c1,c2;
int n1,n2;
c1=getchar();
c2=getchar();
n1=c1-'0';n2= n1*10+(c2-'0');
printf("%d\n",n2);
}
程序运行时输入:12<回车>,执行后输出结果是什么?
相关知识:①getchar()函数用来输入两个字符分别赋给变量c1和c2;
②n1=c1-'0'相当于n1='1' -'0',字符1的ASCII码值比0大一,所以n1中的值为1,c2-'0'相当于'2' -'0';
③把字符串转换为多位数的算法。
3.若有以下程序
#include
void main()
{ int i,j;
int x,y;
scanf("i=%d,j=%d",&i,&j);
scanf("%d%d",&x,&y);
printf("i=%d,j=%d\n",i,j);
printf("%4d%4d\n",x,y);
}
要求给i赋值为10,j赋值为20,则应该怎样从键盘输入数字?
相关知识:①在调用scanf()函数时在格式串中若包含有格式描述符之外的字符时,则要求在输入数据时在对应的位置上输入完全匹配的字符;
②scanf()函数只包含格式描述符时可用跳格键Tab、空格和回车分隔数据;
③在调用printf ()函数时在格式串中若包含有格式描述符之外的字符时,则在输出数据时在对应的位置上输出完全匹配的字符,%d之类的格式符位置输出对应输出项的值;故输出时要注意插入适当的非格式符以便区分各个输出结果。
4. 计算定期存款本利之和
设银行定期存款的年利率rate为2.25%,并已知存款期为n年,存款本金为capital元,试编程计算n年后的本利之和deposit。要求定期存款的年利率rate、存款期n和存款本金capital均由键盘输入。
实验二逻辑结构程序设计
一、实验目的
1. 了解C语言表示逻辑量的方法。
2. 学会正确使用逻辑运算符和逻辑表达式
3. 熟练掌握if 语句和 switch语句。
4. 结合程序掌握一些简单的算法。
5. 学习调试程序。
二、实验内容和步骤
1. 若输入10,20,30则程序的执行结果是 20,30,10 请填充程序。
# include “stdio.h”
void main( )
{ int a, b, c ;
scanf(“%d,%d,%d”,&a,&b,&c);
int t;
t=a;
a=b ;
b=c ;
c=t;
printf ( "%d,%d,%d" ,a, b, c );
}
2. 源程序中包含有一些错误,调试下列程序,使之具有如下功能:输入a、b、c三个整数,求最小值。
# include “stdio.h”
void main( )
{ int a,b,c;
scanf("%d%d%d",a,b,c);
if((a>b)&&(a>c))
if(b printf("min=%d\n",b); else printf("min=%d\n",c); if((a printf("min=%d\n",a); } 再次运行程序,输入为“2,1,3”,程序输出却是“min=2”。用单步执行的方法,马上发现变量a 、b 、c 的值是不对的,原因是程序要求输入数据的分隔符是空格(还允许使用回车或 void main() { int a,b,c; scanf("%d%d%d",&a,&b,&c); if((a printf("min=%d\n",a) else if((b printf("No find minimum\n"); } 上述程序是按在三个数中仅有一个最小值时才称其为最小值进行设计的。另外,注意程序的书写格式,一定要采用缩进格式,即不同层次(分支)的语句左起的空格不同,这样可以有效地提高程序的可读性。 相关知识:①类似a 3.参考上一题,编写一个C 程序,求a 、b 、c 、d 四个数中的最大者。 编程点拨: ①多定义一个变量,并一开始令变量max=a; ②if(max 4.输入4个整数,要求按由小到大顺序输出。得到正确结果后,修改程序使之按由大到小顺序输出。 相关知识:①输入函数scanf()的使用;②简单的排序算法;③通过中间变量t 交换a 和b 值的方法:t=a; a=b; b=t;。 5.根据以下函数关系,对输入的每个x 值,计算出相应的y 值。 #include ?? ? ??+-=)sin(2 ||12x x e y x 4310≤≤≤≤x x 当x 取其他值时 #include if ( (x>=0)&&(x<=1) ) y=exp(sqrt(x))-1 ; else if ((x>=3)&&(x<=4) ) y=fabs(x)+2 ; else y=sin(x*x) printf("x=%f,y=%f",x,y); } 相关知识点:if 语句的嵌套;数学函数的调用方式。 6.模仿第5题,写程序实现以下函数: ??? ??>-≤≤-<=)10(113)101(12)1(x x x x x x y 用scanf 函数输入x 的值,求y 值。运行程序,输入x 的值(分别为x<1、1≤x<10、x≥10三种情况),检查输出的y 值是否正确。 相关知识:①用if 的嵌套实现分段函数;②比较运算符的正确使用;③算术运算符*的正确使用。 7.阅读分析以下程序的功能。 #include printf("Convert:\n"); /* 显示菜单 */ printf(" 1:decimal (十进制)to hexadecimal (十六进制)\n "); printf(" 2:hexadecimal to decimal\n "); printf(" 3:decimal to octal (八进制)\n "); printf(" 4:octal to decimal\n"); printf("enter your choice: "); scanf("%d",&choice); switch (choice) { case 1: /* 选中1时处理 */ printf("enter decimal value:"); scanf("%d",&value); printf("%d in hexadecimal is:%x\n",value,value); break; case 2: /* 选中2时处理 */ printf("enter hexadecimal value:"); scanf("%x",&value); printf("%x in decimal is:%d\n",value,value); break; case 3: /* 选中3时处理 */ printf("enter decimal value:"); scanf("%d",&value); printf("%d in octal is:%o\n",value,value); break; case 4: /* 选中4时处理 */ printf("enter octal value:"); scanf("%o",&value); printf("%o in decimal is:%d\n",value,value); break; } } 相关知识:①用switch语句实现菜单的方法;②数制转换的方法。 8.编写一程序,要求对输入的数字1~7转换成文字星期几,对其它数字不转换。例如,输入5时,程序应该输出Friday。 ①编辑、调试和运行该程序,然后输入4。其输出结果是什么?为什 么是这样的结果? ②该程序有哪些错误?如何修改? 相关知识:①switch语句的正确使用;②break在switch语句中的作用。 实验三循环控制 一、实验目的 1. 熟练掌握用while语句、do while语句和for语句实现循环的方法。 2. 掌握在程序设计中用循的方法实现一些常用算法。并进一步学习调试程序的方法。 二、实验内容和步骤 1.程序求和:1+…+100,填空,实现该功能。 #include void main() { int s,i; s=0; /* 第5行 */ for( ) s=s+i; printf("1+...+100=%d\n",s); } 思考:(1)第5行能不能去掉?其作用是什么? (2)不用for语句,用while语句改写该程序,实现同样的功能。 2.比较下列两个程序。(验证) /* 第一个程序 */ #include void main() { int i,n,sum=0; scanf("%d",&i); n=i; while(i<=10) { sum+=i; i++; } printf("%d+...+10=%d",n,sum); } /* 第二个程序 */ #include void main() { int i,n,sum=0; scanf("%d",&i); n=i; do { sum+=i; i++; } while(i<=10); printf("%d+...+10=%d",n,sum); } 分别运行这两题,若输入7,这两个程序的结果分别是多少?若输入12,这两个程序的结果又分别是多少?比较为什么会有这样的区别? 3.预习下面程序,若输入12345,分析输出结果是多少?上机验证。 #include void main( ) { long data; scanf("%ld",&data); while(data) { printf("%ld,",data%10); data=data/10; } } 4. 实现求Fibonacci 数列的前n 个数。(验证、调试) ?? ? ≥+===--3 2112 1n F F n n F n n n 或 运行程序,写出运行结果;采用单步跟踪技术运行该程序,观察一下变量的变化。 #include { long int f1, f2; int i,n; printf("Input n:"); /* 第5行 */ scanf("%d",&n); /* 第6行 */ f1=f2=1; for(i=1;i { printf("%ld\t%ld\n",f1,f2); /* 第9行 */ f1=f1+f2; f2=f2+f1; } } 思考:(1)f1、f2这两个变量为什么定义为long int 型? (2)第5行和第6行的相互作用,你会用这种方式来实现输入 吗? (3)注意第9行的输出“%ld ”中的“1”是字母“L ”的小写形 式,不是数字1。 5. 预习下面程序,写出预习结果并上机验证。(验证) #include { int i,j,x; for(i=0,x=0;i<2;i++) { x++; for(j=0;j<3;j++) { if(j%2) continue; x++; } x++; } printf("x=%d\n", x); } 思考:用一句话概括if(j%2)语句的作用。 相关知识:嵌套for循环的执行过程及continue语句的作用。 6.输入一批考试分数,用 1作为结束标志,若输入大于100分,则提示 重新输入,然后计算最高分、最低分与平均分。请调试、检查程序中的错误, 并改正之。 #include void main( ) { int mark; int n=0 ; sum=0 ; int max=100 ; min=0 ; for ( ; ; ) ; { scanf("%d", &mark); if ( mark > 100 ) { printf(" Mark > 100 , Please reinput \n "); break; } if ( mark=-1) break; n ++ ; sum=sum + mark ; if( mark > max ) max = mark ; if( mark < min ) min = mark ; } sum=sum/ n ; printf("max =%d , min = %d, aver = %d \n", max , min , sum); } 提示:该程序有很多错误,下面给出某些错误的说明。当求一批数中的最大值时,若已知一批数的最小值,则将这个最小值作为最大 值的初始值;当求最小值时,情况相反,即若已知这批数的最大 值,则将这个最大值作为最小值的初始值。本例中求一批分数的 最高分,则最高分的初始值应该设为0,然后在程序循环中逐渐 地升高,直至求出最高分;本例中还要求这批分数的最低分,则 最低分的初始值设为100,然后在程序循环中逐渐地降低,直至 求出最小值。实现“若输入大于100分,则提示重新输入”功能 的语句有错;实现“用 1作为结束标志”功能的语句有错。 思考:(1)“一批数据”是几个数据?输入的数据如何结束?程序中哪一行是实现结束这个要求的,写出该语句。 (2)程序中哪个语句是实现”若输入大于100分,则提示重新输 入”这个要求的,写出该语句。 (3)写出您的测试数据及运行结果,注意输入的数据序列中最后 一个应是-1。 7.编程:输入20个1~90的整数,分类统计1~30、31~60、61~90的数各有多少个? 编程点拨: (1)count1计1~30的个数,count2计31~60的个数,count3计61~ 90的个数。 (2)用for循环20次实现该程序的功能:输入一个整数x,判断该数所 在的范围,若x是1~30,则count1加1;若x是31~60,则count2 加1;若x是61~90,则count3加1。 (3)最后,输出统计的结果。 #include void main( ) { int count1=0,count2=0,count3=0; int i,x; printf(“Please input 20 numbers:”); for(i=0;i<20;i++) { scanf(“%d”,&x); ……… /*补充完成程序*/ } /* 输出统计结果 */ …………… } 8.编程:素数是除了1和其本身以外,不能被其他自然数整除的自然数。从键盘输入一个数,判断该数是不是素数? 编程点拨: a)输入这个数x。 b)用for循环2~x-1,用2~x-1的每一个数去除x,若有一个数 整除x,则说明x不是素数;否则,x就是素数。 c)最后,将判断结果输出。 #include printf("Enter one natural integer: "); scanf("%d ",&x); for(i=2;i 思考:其实,只需要判断2~x 之间的整数能否整除x 就可以判断x 是否为素数,此时,如何修改程序? 9.编程:显示所有的水仙花数。谓水仙花数,是指一个3位数,其各位数字立方和等于该数字本身。例,153是水仙花数,因为153=13+53+33 。有两种解题思路,选择其中之一编程实现: (1) 利用三重循环,将这三个数通过一定的运算符连接成一个3位数, 然后判断是否是水仙花数。 for(i=1;i<=9;i++) for(j=0;j<=9;j++) for(k=0;k<=9;k++) 注意,因水仙花是一个三位数,百位i 是从1开始,不能从0开始,十位j 和个数位k 可以从0开始。 (2) 利用一个循环,对100~999范围内的每个3位数逐位分离后进行 判断。 for(i=100;i<999;i++) { a=i/100; b=(i-a*100)/10; c=i%10; ……… } 10.编程:输出下列图形。 分析:这是由星号构成的5行5列的三角形图形。每一行的星号数量为:1、3、5、7、9。考虑两点,一是每一行上星号的生成规则,二是每一行第一个星号字符的输出位置。每一行的星号与行号有关,即2*i+1,其中i 是行号;每一行的输出位置比上一行少一个空格,可以这样实现:for(j=1;j<=40-i;j++) printf(“%c”, ‘ ’),其中i 是行号。 * *** ***** ******* ********* 实验四数组 一、实验目的及要求: (1)掌握一维数组和二维数组的定义、赋值和输入输出的方法; (2)掌握字符数组和字符串函数的使用; (3)掌握与数组有关的算法(特别是排序算法)。 二、实验内容和步骤 1.调试下列程序,使之具有如下功能:输入10个整数,按每行3个数输出这些整数,最后输出10个整数的平均值。写出调试过程。 #inclue #define N 10 void main( ) { int i,a[N],av; for(i=0;i scanf("%d",a[i]); for(i=0;i { printf("%d",a[i]); if(i%3==0) printf("\n"); } for(i=0;i!=N;i++) av+=a[i]; printf("av=%f\n",av); } 上面给出的程序是完全可以运行的,但是运行结果是完全错误的。调试时请注意数组元素的输入问题、输出格式问题等。请使用前面实验所掌握的调试工具,判断程序中的错误并改正。 相关知识:①数组元素值的输入;②求和求平均值的相关变量初始化问题;③输出格式符的正确使用。④数组元素的格式化输出。 2.下面程序是输入5个数据,然后求它们的和并输出结果。 #include void main( ) {int i, a[5], sum = 0; scanf("%d,%d,%d,%d,%d", a ); for (i = 0; i <= 4; i ++) sum += a[i]; printf("sum = %d \n", sum); } 该程序中有哪些错误?如何修改?写出正确运行后的结果。 相关知识:数组元素的输入和输出只能逐个元素操作,而不能以数组名作整体操作。 3.有一个3行4列的距阵,现要求编程求出其中最大的那个元素的值,以及它所在的行号与列号。程序的初始说明和输出语句如下所示,请补充完成该程序。 #include void main( ) { int i, j, row, colum, max; static int a[3][4] = {{1,2,3,4}, {9,8,7,6}, {-10,10,-5,2}}; …… printf(" Max = %d, Row = %d, Colum = %d \n", max, row, colum); } 编程点拨: ① 初始化row、colum及max。 ② 使用for循环的双重循环逐行把元素值与max值进行比较, 比较结果如果元素值比max值大,则改变max值,同时改变 row和colum的值。 ③最后输出max,row和colum的值。 相关知识:①二维数组的定义和初始化;②使用二重循环对二维数组元素的访问;③求最值时相关变量初值的设定。 4.数组中已存互不相同的10个整数,从键盘输入一个整数,输出与该值相同的数组元素下标。 编程点拨: ①输入要查找的变量x的值; ②使用循环将输入的数和数组元素逐个进行比较,若找到,则提前退出 循环; ③根据循环是正常结束还是提前结束来判断是否找到x。 部分源代码: #include void main( ) { int i, x, a[10]={1,2,3,4,5,6,7,8,9,10}; /*输入x变量的值 */ for ( i=0; i<10; i++ ) printf("%4d",a[i]); printf("\n"); /* 循环查找与x 相等的元素 */ if ( ) printf("%d\n",i); /* 输出查找结论 ,输出 下标值 */ else printf("Not found %d\n",x); } 5.编写程序,任意输入10个整数的数列,先将整数按照从大到小的顺序进行排序,然后输入一个整数插入到数列中,使数列保持从大到小的顺序。 编程点拨: ① 定义数组时多开辟一个存储单元; ② 找合适的插入位置; j=0 a[j] ≥k? 即20 ≥15 ? 是 j++ j=1 a[j] ≥k? 即18 ≥15 ? 是 j++ j=2 a[j] ≥k? 即16 ≥15 ? 是 j++ j=3 a[j] ≥k? 即14 ≥15 ? 不是,结束循环 while( a[j]>=k && j<10 ) j++; 找不到比k 小的元素时也要退出循环 ③ 向右移动插入点后的元素;先把a[9]移到a[10],a[8]移到 a[9],…a[i]移到a[i+1],直到把a[j]移到a[j+1],即:i=j 停止移动元素。 for(i=9;i>=j;i-- ) a[i+1]=a[i]; 20 18 16 14 12 10 8 6 4 2 a 1 2 3 4 5 6 7 8 9 下标= 10 k 15 找合适的插入位置:j=3 j=3 k=0; for ( i=1; i<10; i++ ) if ( a[k] 部分源代码: #include { int i,j,a[N]; printf(“Please input 10 numbers:”); for (i=0; i scanf(“%d ”,&a[i]); /*乱序输入10个整数*/ …… } 相关知识:①比较排序法、选择排序法和冒泡排序法;②数据元素的 插入。 6.输入十个互不相同的整数并存在数组中,找出最大元素,并删除。 编程点拨: ① 求最大值所在元素下标:不必用max 记住最大值,只要用k 记住最大值所在的元素下标; ② 删除最大值:从最大值开始将其后面元素依次前移一个位置。 部分源代码: k=0; if ( a[k]