C语言集中实训指导书.docx
《C语言集中实训指导书.docx》由会员分享,可在线阅读,更多相关《C语言集中实训指导书.docx(31页珍藏版)》请在冰豆网上搜索。
C语言集中实训指导书
重庆工贸职业技术学院
《C语言》集中实训指导书
计算机应用技术教研室
第一章实训的总目的和要求
程序设计是实践性很强的过程,任何程序最终都必须在计算机上运行,以检验程序的正确与否。
因此在学习完C程序设计后,一定要重视上机实践环节,安排一周的实习时间,即独立编写出程序,独立上机调试程序。
通过上机实习可以加深理解C语言的有关概念,以巩固理论知识,另一方面也可以培养程序调试的能力与技巧。
上机实习的目的,绝不仅是为了验证教材和讲课的内容或者验证自己所编的程序正确与否。
应该说,学习程序设计,上机实习的目的为:
(1)加深对讲授内容的理解,尤其是一些语法规则,光靠课堂讲授和很少学时的实验。
既枯燥又难以彻底消化吸收,但它们都很重要。
通过实习,就能熟练地掌握。
(2)进一步熟悉所用的计算机系统的操作方法,也就是熟悉C语言程序的开发环境。
一个程序必须在一定的外部环境下才能运行,所谓“环境”,就是指所用的计算机系统的硬件和软件条件。
使用者应该了解为了运行一个C程序,需要哪些必要的外部条件(例如硬件配置和软件配置),可以利用哪些系统的功能来帮助自己开发程序。
(3)熟练地掌握上机调试程序的方法。
对程序设计来说,要求会编程序并上机调试通过。
因此调试程序本身是程序设计课程的一个重要的内容和基本要求,应充分地重视。
调试程序的经验固然可以借鉴他人的现成经验,但更重要的是通过自己的直接实践来积累,而且有些经验是只能“会意”难以“言传”。
因此,在实习中千万不要在程序通过后就认为万事大吉、完成任务了,而应当在已通过的程序基础上作一些改动(例如修改一些参数、增加程序一些功能、改变输入数据的方法等),再进行编译、连接和运行。
甚至于“自设障碍”,即把正确的程序改为有错的(例如用scanf函数函数输入变量时,漏写“&”符号,使数组下标趆界,使整数溢出等),观察和分析所出现的情况。
这样的学习才会真正有收获,是灵活主动的学习而不是呆板被动的学习,也才能达到实习的目的。
C语言程序的编译和运行
按照C语言语法规则而编写的C程序称为源程序。
源程序由字母、数字及其它符号等构成,在计算机内部用相应的ASCII码表示,并保存在扩展名为“.C”的文件中。
源程序是无法直接被计算机运行的,因为计算机的CPU只能执行二进制的机器指令。
这就需要把ASCII码的源程序先翻译成机器指令,然后计算机的CPU才能运行翻译好的程序。
源程序翻译过程由两个步骤实现:
编译与连接。
首先对源程序进行编译处理,即把每一条语句用若干条机器指令来实现,以生成由机器指令组成的目标程序。
但目标程序还不能马上交计算机直接运行,因为在源程序中,输入、输出以及常用函数运算并不是用户自己编写的,而直接调用系统函数库中的库函数。
因此,必须把“库函数”的处理过程连接到经编译生成的目标程序中,生成可执行程序,并经机器指令的地址重定位,便可由计算机运行,最终得到结果。
C语言程序的调试、运行步骤可以用图1表示:
图1C语言程序的调试、运行步骤
图1中,虚线表示当某一步骤出现错误时的修改路线。
运行时,无论是出现编译错误、连接错误,还是运行结果不对(源程序中有语法错误或逻辑错误),都需要修改源程序,并对它重新编译、连接和运行,直至将程序调试正确为止。
第三章实训内容
3.2简单的C程序设计
【目的与要求】
1.理解C语言程序的顺序结构
2.掌握常用的C语言语句,熟练应用赋值、输入、输出语句。
【上机内容】
【一般实例】
【例1】按格式要求输入/输出数据
#include"stdio.h"
main()
{
inta,b;
flostx,y;
charc1,c2;
scanf(“a=%d,b=%d”,&a,&b);
scanf(“%f,%e”,&x,&y);
scanf(“&c&c”,&c1,&c2);
printf(“a=%d,b=%d,x=%f,y=%f,c1=%c,c2=%c\n”,a,b,x,y,c1,c2);
}
运行该程序,必须按如下方式在键盘上输入数据
a=3,b=7↙
8.5,71.82↙
aA↙
请同学们写出输出结果
【例2】输入三角形三边长,求三角形面积。
#include“math.h”
main()
{
floata,b,c,s,area;
scanf(“%f,%f,%f”,&a,&b,&c);
s=1.0/2*(a+b+c);
area=sqrt(s*(s-a)*(s-b)*(s-c));
printf(“area=%f”,area);
}
【例3】已知圆半径,圆柱高,求圆周长,圆柱体积。
main()
{
floatr,h,l,v,pi;
pi=3.1415926;
scanf(“%f,%f”,&r,&h);
l=2*pi*r;
v=pi*r*r*h;
printf(“圆周长为:
%6.2f\n”,l);
printf(“%圆柱体积为:
6.2f”,v);
}
【例4】输入一个摄氏温度,要求输出华氏温度。
公式为f=5/9*c+32.
main()
{
floatc,f;
scanf(“%f”,&c);
f=5.0/9*c+32;
printf(“%5.2f\n”,c);
}
【作业】
1.已知圆半径r=1.5,圆柱高h=3,求圆周长,圆面积,圆球表面积,圆球体积,圆柱体积。
2.输入一个华氏温度,要求输出摄氏温度。
公式为c=5/9*(f-32).
3.3选择结构程序设计
【目的与要求】
1.了解C语句表示逻辑量的方法(以0代表“假”以1代表“真”);
2.学会正确使用逻辑运算符和逻辑表达式;
3.熟练掌握if语句和switch语句。
【上机内容】
【一般示例】
【例1】已知三个数a,b,c,找出最大值放于max中。
分析:
由已知可得在变量定义时定义四个变量a,b,c和max,a,b,c是任意输入的三个数,max是用来存放结果最大值的。
第一次比较a和b,把大数存入max中,因a,b都可能是大值,所以用if语句中if——else
形式。
第二次比较max和c,把最大数存入max中,用if语句的第一种形式if形式。
Max即为a,b,c中的最大值。
#include"stdio.h"
main()
{
inta,b,c,max;/*定义四个整型变量*/
scanf(“a=%d,b=%d,c=%d”,&a,&b,&c);
if(a>=b)
max=a;/*a>=b*/
else
max=b;/*a
if(c>max)
max=c;/*c是最大值*/
printf("max=%d",max);
}
若输入下列数据,分析程序的执行顺序并写出运行结果
(1)a=1,b=2,c=3
(2)a=2,b=1,c=3
(3)a=3,b=2,c=1
(4)a=3,b=1,c=2
(5)a=3,b=3,c=2
(6)a=2,b=1,c=2
【例2】输入某学生的成绩,经处理后给出学生的等级,等级分类如下:
90分以上(包括90):
A
80至90分(包括80):
B
70至80分(包括70):
C
60至70分(包括60):
D
60分以下:
E
方法一:
(用if嵌套`)
分析:
由题意知如果某学生成绩在90分以上,等级为A;否则,如果成绩大于80分,等级为B;否则,如果成绩大于70分,等级为C;否则,如果成绩大于60分为D;否则,如果成绩小于60分,等级为E;但当我们输入成绩时也可能输错,出现小于0或大于100,这时也要做处理,输出出错信息。
因此,再用if嵌套前,应先判断输入的成绩是否在0~100之间。
#include"stdio.h"
main()
{
intscore;
chargrade;
printf("\npleaseinputastudentscore:
");
scanf("%f",&score);
if(score>100||score<0)
printf("\ninputerror!
");
else
{if(score>=90)
grade='A';
else
{if(score>=80)
grade='B';
else
{if(score>=70)
grade='C';
else
{if(score>=60)
grade='D';
elsegrade='E';
}
}
}
printf("\nthestudentgrade:
%c",grade);
}
}
输入测试数据,调试程序。
测试数据要覆盖所有路径,注意临界值,例如此题中得100分,60分,0分以及小于0和大于100的数据。
方法二:
用switch语句
分析:
switch
语句是用于处理多分支的语句。
注意,case后的表达式必须是一个常量表达式,所以在以用switch语句之前,必须把0~100之间的成绩分别化成相关的常量。
所有A(除100以外),B,C,D类的成绩的共同特点是十位数相同,此外都是E类。
则由此可得把score除十取整,化为相应的常数。
#include"stdio.h"
main()
{
intg,s;
charch;
printf("\ninputastudentgrade:
");
scanf("%d",&g);
s=g/10;
if(s<0||s>10)
printf("\ninputerror!
");
else
{switch(s)
{case10:
case9:
ch='A';break;
case8:
ch='B';break;
case7:
ch='C';break;
case6:
ch='D';break;
default:
ch='E';
}
printf("\nthestudentscort:
%c",ch);
}
}
输入测试数据,同方法一一样调试程序并写出结果。
【例3】有一函数:
x(x<1)
y=2x-1(1≤x<10)
3x-11(x≥10)
用scanf函数输入x的值(分别为x<1,1~10,>=10三种情况),求y值。
分析:
y是一个分段表达式。
要根据x的不同区间来计算y的值。
所以应使用If语句。
main()
{
intx,y;
printf(“pleaseinputx:
”);
scanf(“%d”,&x);
if(x<1)
{
y=x;
printf(“y=%d\n”,y);
}
elseif(x<10)
{
y=2*x-1;
printf(“y=%d\n”,y);
}
else
{
y=3*x-11;
printf(“y=%d\n”,y);
}
【作业】
1.c语言如何表示“真”与“假”?
系统如何判断一个量的“真”与“假”?
2.写出下面各逻辑表达式的值。
设a=3,b=4,c=5
(1)a+b>c&&b==c
(2)a||b+c&&b-c
(3)!
(a>b)&&!
c||1
(4)!
(x=a)&&(y=b)&&0
(5)!
(a+b)+c-1&&b+c/2
3.有3个整数a、b、c,由键盘输入,输出其中最大的数。
4.有一函数:
x(x<1)
y=2x-1(13x-11(x>10)
写一程序,输入x,输出y。
5.给出一百分制成绩,要求输出成绩等级A、B、C、D、E。
90分以上为A,80~89为B,70~79分为C,60~69分为D,60分以下为E。
6.给一个不多于5位的正整数,要求:
a.求出它是几位数;
b.分别打出每一位数字;
c.按逆序打出各位数字,例如原数为321,应输出123。
7.输入4个整数,要求按由小到大的顺序输出。
3.4循环结构程序设计
【目的与要求】
熟练掌握while、do—while和for三种循环语句的应用。
【上机内容】
【一般示例】
【例1】求5!
main()
{
intn,t;
n=1;
t=1;
while(t<=5)
{
n=n*t;
t=t+1;
}
printf(“%d”,n);
}
【例2】求和s=1!
+2!
+3!
main()
{
intn,s=0,t=1;
for(n=1;n<=3;n++)
{
t=t*n;
s=s+t;
}
printf(“%d”,s);
}
【例3】求和s=1!
+3!
+5!
main()
{
ints=0,t,i,j;
for(i=1;i<=3;i++)
{
t=1;
for(j=1;j<=2*i-1;j++)
t=t*j;
s=s+t;
}
printf(“%d”,s);
}
【例4】求和s=3+33+333
main()
{
ints=0,t=3,i;
for(i=1;i<=3;i++)
{
s=s+t;
t=10*t+3;
}
printf(“%d”,s);
}
【例5】有一数列:
2/1,3/2,5/3,8/5,…求出这个数列的前10项之和。
main()
{
intn,t,;
floata=2,b=1,s=0;
for(n=1;n<=10;n++)
{
s=s+a/b;
t=a;
a=a+b;
b=t;
}
printf(“%f”,s);
}
【例6】打印500以内的“水仙花数”。
“水仙花数”是一个三位数,其各位数立方和等于该数本身。
main()
{
inti,j,k,n;
for(n=100;n<=500;n++)
{
i=n/100;
j=n/10-i*10;
k=n%10;
if(n==i*i*i+j*j*j+k*k*k)
printf(“%d”,n);
}
}
【例7】一个数如果恰好等于它的因子之和,这个数就称为完数。
求100之内的所有完数。
main()
{
intn,s,j;
for(n=1;n<=100;n++)
{
s=0;
for(j=1;jif(n%j==0)
s=s+j;
if(s==n)
printf(“%d”,s);
}
}
【典型示例】
【例1】计算两个数的最大公约数;
分析:
首先,随机输入两个数m,n(默认m>n);其次,算法:
使k为m除以n的余数,如果m能被n整除,则k值为0,n为这两个数的最大公约数,否则,使k代替n,n代替m,重复以上过程,直到k值为0。
#include"stdio.h"
main()
{
intm,n,k,result;
printf("Entertwonumbers:
");
scanf("%d,%d",&m,&n);
if(m>0&&n>0)/*限定两个正整数*/
{
do
{
k=n%m;
if(k==0)
result=m;
else
{
n=m;
m=k;
}
}while(k>0);/*循环取余求出最大公因子*/
printf("Thegreatestcommondivistoris:
%d\n",result);
}
elseprintf("Nonpositivevaluesnotallowed\n");
}
【例2】用牛顿迭代求方程2x3-4x2+3x-6=0在1.0附近的根。
#include“math.h”
main()
{
floatx,x0,f,f1;
x=1.0;
do
{x0=x;
f=((2*x0-4)*x0+3)*x0-6;
f1=(6*x0-8)*x0+3;
x=x0-f/f1;
}
while(fabs(x-x0)>=1e-5);
printf(“%6.2f”,x);
}
【例3】打印下列图案
*
***
*****
*******
main()
{inti,j;
for(i=1;i<=4;i++)
{for(j=1;j<=4-i;j++)
printf(“”);
for(j=1;j<=2*i-1;j++)
printf(“*”);
printf(“\n”);
}
}
【例4】判断m是否是素数。
程序:
#include
main()
{
intm,i,k;
scanf(“%d”,&m);
k=sqrt(m+1);
for(i=2;i<=k;i++)
if(m%i==0)
break;
if(i>=k+1)
printf(“%disaprimenumber\n”,m);
else
printf(“%disnotaprimenumber\n”,m);
}
【作业】
1.输入两个正整数m和n,求其最大公约数和最小公倍数。
2.求Sn=a+aa+aaa+…+aa…a之值,其中a是一个数字。
例如:
2+22+222+2222+22222(此时n=5),n由键盘输入。
3.求和1!
+2!
+3!
+4!
+…20!
4.打印100-999之间所有的“水仙花数”。
“水仙花数”是一个三位数,其各位数立方和等于该数本身。
5.一个数如果恰好等于它的因子之和,这个数就称为完数。
求1000之内的所有完数。
6.有一数列:
2/1,3/2,5/3,8/5,…求出这个数列的前20项之和。
7.用迭代法求x=√a。
求平方根的迭公式为
xn+1=1/2(xn+a/xn)
要求前后两次求出的x的差的绝对值小于10-5
8.用牛顿迭代求方程2x3-4x2+3x-6=0在1.5附近的根。
9.打印下列图案
*
***
*****
***
*
3.5一维数组
【目的与要求】
1.掌握一维数组的定义、赋值和输入输出的方法;
2.掌握字符数组的使用;
3.掌握与数组有关的算法(例如排序算法)。
【上机内容】
【一般示例】
【例1】在键盘上输入N个整数,试编制程序使该数组中的数按照从大到小的次序排列。
分析:
C中数组长度必须是确定大小,即指定N的值。
排序的方法有多种,我们取出其中两种作为参考。
方法一:
起泡排序
从第一个数开始依次对相邻两数进行比较,如次序对则不做任何操作;如次序不对则使这两个数交换位置。
第一遍的(N-1)次比较后,最大的数已放在最后,第二遍只需考虑(N-1)个数,以此类推直到第(N-1)遍比较后就可以完成排序。
源程序如下:
#defineN10
#include"stdio.h"
main()
{
inta[N],i,j,temp;
printf("pleaseinput%dnumbers\n",N);
for(i=0;iscanf("%d",&a[i]);
for(i=0;ifor(j=0;j{
if(a[j]>a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
printf("thearrayaftersort:
\n");
for(i=0;iprintf("%5d",a[i]);
}
方法二:
选择排序
首先找出值最小的数,然后把这个数与第一个数交换,这样值最小的数就放到了第一个位置;然后,在从剩下的数中找值最小的,把它和第二个数互换,使得第二小的数放在第二个位置上。
以此类推,直到所有的值从小到大的顺序排列为止。
#include"stdio.h"
#defineN10
main()
{
inta[N],i,j,r,temp;
printf("pleaseinput%dnumbers\n",N);
for(i=0;iscanf("%d",&a[i]);
for(i=0;i{r=i;
for(j=i+1;jif(a[j]r=j;
if(r!
=i)
{
temp=a[r];
a[r]=a[i];
a[i]=temp;
}
}
printf("thearrayaftersort:
\n");
for(i=0;iprintf("%5d",a[i]);
printf("\n");
}
【例2】青年歌手参加歌曲大奖赛,有10个评委对她的进行打分,试编程求这位选手的平均得分(去掉一个最高分和一个最低分)。
分析:
这道题的核心是排序。
将评委所打的10个分数利用数组按增序(或降序)排列,计算数组中除第一个和最后一个分数以外的数的平均分,其中排序部分这里用选择法实现。
main()
{inti,j,min;
floattemp,ave=0;
floata[11];
printf("\n输入评委所打的分数:
\n");
for(i=1;i<=10;i++)
scanf("%f",&a[i]);
for(i=1;i<=9;i++)
{min=i;
for(j=i+1;j<=10;j++)
if(a[min]>a[j])
min=j;
temp=a[i];
a[i]=a[min];
a[min]=temp;
}
for(i=2;i<=9;i++)/*注意i值的变化范围*/
ave=ave+a[i];
printf("选手所得最后分数:
%6.1f",ave/8);
printf("\n");
}
【例3】输入一串字符,计算其中空格的个数。
#include
main()
{charc[30];
inti,sum=0;
gets(c);
for(i=0;iif(c[i]=='')
sum=sum+1;
printf("空格数为:
%d\n",sum);
}
【作业】
1.已有一个已排好序的数组,今输入一个数,要求按原来排序的规律将它插入数组中。
2.将一个数组中的值按逆序重新存放。
例如,原来顺序为8,6,5,4,1。
要求改为1,4,5,6,8。
3.有15个数按由小到大顺序存放在一个数组中,输入一个数,要求用折半查找法找出该数是数组中第几个元素的值。
如果该数不在数组中,则打印出“无此数”。
4.编一程序,将两个字符串连接起来,不要用strcat函数。
3.6二维数组
【目的与要求】
1.掌握二维数组的定义、赋值和输入输出的方法;
2.掌握字符数组的使用;
3.掌握与数组有关的算法(例如排序算法)。
【上机内容】
【一般示例】
【例1】有一个3×4的矩阵,要求输出其中值最大的元素的值,以及它的行号和列号。
#defineM3
#defineN4
main()
{intmax,i,j,r,c;
s