实验教学
C程序设计实验
学时:90(理论课54+实验课36) 学分:4
课程属性:相关学科基础课 开课单位:数学与信息科学学院
先修课程:无
一、实验性质
C程序设计实验是理论课《C程序设计》所配套的实践课程,通过上机实践,使学生更好地掌握C语言的基本内容、程序设计的基本方法与编程技巧,培养学生应用计算机解决和处理实际问题的思维方法与基本能力,为提高学生的素质和后继课程的学习提供必要的基础.
二、实验教学目的和要求
实验教学目的主要包括:
1. 熟练掌握VC++6.0 环境下C程序的编写、调试和运行的基本流程.
2. 掌握结构化程序设计思想和最基本算法的设计.
3. 掌握C语言程序设计的方法及编程技巧,能正确使用C语言编写程序.
4. 掌握调试程序的基本方法.
要求学生在学习过程中必须注意理论与实践相结合.在上机实验前,应仔细阅读教材,熟悉相关概念和算法,实验后认真填写竞彩网站 C程序设计实验报告.
三、实验项目名称和学时分配
实验项目编号 |
实验项目名称 |
学时 分配 |
实验类型 |
每组 人数 |
必开/选开 |
备 注 |
0521103001 |
Visual C++ 6.0开发环境使用 |
2 |
验证性 |
全班 |
必开 |
|
0521103002 |
数据类型、运算符和表达式 |
2 |
验证性 |
全班 |
必开 |
|
0521103003 |
格式化输入输出函数的使用 |
4 |
验证性 |
全班 |
必开 |
|
0521103004 |
分支结构程序设计 |
4 |
设计性 |
全班 |
必开 |
|
0521103005 |
循环结构程序设计 |
4 |
设计性 |
全班 |
必开 |
|
0521103006 |
函数 |
6 |
设计性 |
全班 |
必开 |
|
0521103007 |
数组及其应用 |
6 |
设计性 |
全班 |
必开 |
|
0521103008 |
指针及其应用 |
6 |
综合性 |
全班 |
必开 |
|
0521103009 |
结构体及其应用 |
4 |
综合性 |
全班 |
必开 |
|
0521103010 |
文件 |
2 |
设计性 |
全班 |
必开 |
注:1. 实验类型指技能训练性、演示性、验证性、综合性、设计性等实验;
2. 实验项目编号规则:共10位,第1-7位为课程编码,第8、9、10位为流水号
四、实验项目具体内容
1. 实验项目:0521103001
实验名称:Visual C++ 6.0开发环境使用
实验目的
(1)熟悉Visual C++ 6.0集成开发环境。
(2)掌握C语言程序的书写格式和C语言程序的结构。
(3)掌握C语言上机步骤,了解C程序的运行方法。
(4)能够熟练地掌握C语言程序的调试方法和步骤。
实验内容
输入如下程序,实现两个数的乘积。
#include<stdio.h>;
int main()
{
x=10,y=20
p=prodct(x,t)
printf("The product is : ",p)
int prodct(int a ,int b )
int c
c=a*b
return c
}
(1)在编辑状态下照原样输入上述程序。
(2)编译并运行上述程序,记下所给出的出错信息。
(3)再编译执行纠错后的程序。如还有错误,再编辑改正,直到不出现语法错误为止。
分析与讨论
(1)记下在调试过程中所发现的错误、系统给出的出错信息和对策。分析讨论成功或失败的原因。
(2)总结C程序的结构和书写规则。
2. 实验项目:0521103002
实验名称: 数据类型、运算符和表达式
实验目的
(1)理解常用运行符的功能、优先级和结合性。
(2)熟练掌握算术表达式的求值规则。
(3)熟练使用赋值表达式。
(4)理解自加、自减运算符和逗号运算符。
(5)掌握关系表达式和逻辑表达式的求值。
实验内容
(1)整数相除
#include<stdio.h>
int main()
{
int a=5,b=7,c=100,d,e,f;
d=a/b*c;
e=a*c/b;
f=c/b*a;
printf("d=%d , e=%d ,f=%d\n",d,e,f);
return 0;
}
(2)自加、自减运算
#include<stdio.h>
int main()
{
int a=5,b=8;
printf("a++=%d\n",a++);
printf("a=%d\n",a);
printf("++b=%d\n",++b);
printf("b=%d\n",b);
return 0;
}
(3)关系运算和逻辑运算
#include<stdio.h>
int main()
{
int a=5,b=8,c=8;
printf("%d,%d,%d,%d\n",a==b&&a==c,a!=b&&a!=c,a>=b&&a>=c,a<=b&&a<=c);
printf("%d,%d\n",a<=b||a>=c,a==b||b==c);
printf("%d,%d,%d,%d\n",!(a==b),!(a>=b),!(a>=c),!(a<=b));
return 0;
}
① 在编辑状态下输入上述程序。
② 编译并运行上述程序。
分析与讨论
(1)整数相除有什么危险?应如何避免这种危险?
(2)分析a++和++a的区别。
(3)条件表达式和逻辑表达式的意义是什么?它们的取值如何?
(4)如何比较两个浮点数相等?为什么?
3. 实验项目:0521103003
实验名称:格式化输入输出函数的使用
实验目的
(1)掌握格式字符使用的方法。
(2)掌握printf()进行格式化输出的方法。
(3)掌握scanf()进行格式化输入的方法。
实验内容
(1)输入如下程序,观察运行结果
#include<stdio.h>
int main()
{
int x=1234;
float f=123.456;
double m=123.456;
char ch='a';
char a[]="Hello,world!";
int y=3,z=4;
printf("%d %d\n",y,z);
printf("y=%d , z=%d\n",y,z);
printf("%8d,%2d\n",x,x);
printf("%f,%8f,%8.1f,%.2f,%.2e\n",f,f,f,f,f);
printf("%lf\n",m);
printf("%3c\n",ch);
printf("%s\n%15s\n%10.5s\n%2.5s\n%.3s\n",a,a,a,a,a);
return 0;
}
(2)输入下面程序,观察调试信息
#include<stdio.h>
int main()
{
double x,y;
char c1,c2,c3;
int a1,a2,a3;
scanf("%d%d%d",a1,a2,a3);
printf("%d,%d,%d\n",a1,a2,a3);
scanf("%c%c%c",&c1,&c2,&c3);
printf("%c%c%c\n",c1,c2,c3);
scanf("%f,%lf",&x,&y);
printf("%f,%lf\n",x,y);
return 0;
}
① 在VC++ 6.0集成开发环境中输入上述程序,观察调试结果。
② 如果有错误,请修改程序中的错误。
分析与讨论
(1)分析程序错误及运行结果错误的原因。
(2)总结printf()中可使用的各种格式字符。
(3)总结转义字符的使用和功能。
4. 实验项目:0521103004
实验名称:分支结构程序设计
实验目的
(1)了解条件与程序流程的关系。
(2)了解用不同的数据使程序的流程覆盖不同的语句、分支和路径。
(3)掌握if语句和if else语句的用法。
(4)掌握switch语句的用法。
实验内容
(1)从键盘上输入三个数,让它们代表三条线段的长度,请写一个判断这三条线段所组成的三角形属于什么类型(不等边,等腰,等边或不构成三角形)的C程序。 请分别设计下列数据对自己的程序进行测试:
① 找出各条语句中的错误。
② 找出各分支中的错误。
③ 找出各条件中的错误。
④ 找出各种条件组合中的错误。
⑤ 找出各条路径中的错误。
(2)用scanf函数输入一个百分制成绩(整型量),要求输出成绩等级A,B,C,D,E。其中90~100分为A,80~89分为B,70~79分为C,60~69分为D,60分以下为E。具体要求如下:
① 用if语句实现分支或switch分支。
② 在输入百分制成绩前要有提示。
③ 在输入百分制成绩后,要判断该成绩的合理性,对于不合理的成绩(即大于100分或小于0分)应输出出错信息。
④ 在输出结果中应包括百分制成绩与成绩等级,并要有文字说明。
⑤ 分别输入百分制成绩:–90,100,90,85,70,60,45,101,运行该程序。
(3)编程找出5个整数中的最大数和最小数,并输出找到的最大数和最小数。
分析与讨论
(1)总结分支程序设计的方法。
(2)复合语句的使用。
(3)switch语句的注意事项。
5. 实验项目:0521103005
实验名称:循环结构程序设计
实验目的
(1)掌握在程序设计条件型循环结构时,如何正确地设定循环条件,以及如何控制循环的次数。
(2)了解条件型循环结构的基本测试方法。
(3)掌握如何正确地控制计数型循环结构的次数。
(4)了解对计数型循环结构进行测试的基本方法。
(5)了解在嵌套循环结构中,提高程序效率的方法。
实验内容
(1)输入一个正整数,并将其颠倒过来,如12345对应为54321。
(2)将一个长整型数s的每一位数位上的偶数依次取出来,构成一个新的数t,其高位仍在高位,低位仍在低位,例如:s=87653142时,t中的数为8642。
(3)判断101~200之间有多少个素数。
(4)编写程序,输出杨辉三角形。
分析与讨论
(1)总结条件循环结构的一般方法。
(2)如何测试计数型循环结构的控制表达式中的错误?
(3)从实验中你得到了哪些提高嵌套循环程序效率的启示?
6. 实验项目:0521103006
实验名称:函数
实验目的
(1)掌握C语言函数定义及调用的规则。
(2)理解参数传递的过程。
(3)掌握函数返回值的大小和类型确定的方法。
(4)理解变量的作用范围。
实验内容
(1)上机调试下面的程序,记录系统给出的出错信息,并指出出错原因。
#include<stdio.h>
int main()
{
int,y;
printf("%d\n",sum(x+y));
int sum(a,b)
{
int a,b;
return(a+b);
}
return 0;
}
(2)编写一个程序,输入系数a,b,c,求一元二次方程ax2+bx+c=0的根,包括主函数和如下子函数。
① 判断a是否为零。
② 计算判别式。
③ 计算根的情况。
④ 输出根。
(3)输入下面程序,分析运行结果。
#include<stdio.h>
int func (int ,int);
int main ( )
{ int k=4,m=1,p1,p2;
p1=func(k,m) ;
p2=func(k,m) ;
printf("%d,%d\n",p1,p2) ;
return 0;
}
int func (int a,int b)
{ static int m=0,i=2;
i+=m+1;
m=i+a+b;
return (m);
}
分析与讨论
(1)针对以上实验内容写出相应的参数传递过程并分析结果。
(2)函数在定义时要注意什么?
(3)讨论静态局部变量的继承性。
7. 实验项目:0521103007
实验名称:数组及其应用
实验目的
(1)掌握数组定义的规则。
(2)掌握C语言数组的基本用法。
(3)掌握数组名作为函数参数传递的方法。
实验内容
(1)运行下面的C程序,根据运行结果,可以说明什么?
#include <stdio.h>
int main( )
{
int num[5]={1,2,3,4,5};
int i;
for(i=0;i<=5;i++)
printf("%d ",num[i]);
return 0;
}
(2)为一个冒泡排序程序设计测试用例,并测试之。
(3)操作符&用以求一个变量的地址,这在函数scanf中已经使用过了。现在要你设计一个程序,返回一个3×5 的二维数组各元素的地址,并由此说明二维数组中各元素是按什么顺序存储的。
分析与讨论
(1)通过实验,分析定义与引用数组的区别。
(2)数组的作用是什么?
(3)数组名作为参数有什么特点?
8. 实验项目:0521103008
实验名称:指针及其应用
实验目的
(1)掌握变量的指针及其基本用法。
(2)掌握一维数组的指针及其基本用法。
(3)掌握指针变量作为函数的参数时,参数的传递过程及其用法。
实验内容
(1)运行以下程序,并从中了解变量的指针和指针变量的概念。
# include <stdio.h>
int main()
{
int a=5,b=5,*p;
p=&a;
printf("%d ,%ud\n",a,p);
*p=8;
printf("%d ,%ud\n",a,p);
p=&b;
printf("%d ,%ud\n",a,p);
b=10;
printf("%d ,%ud\n",a,p);
return 0;
}
(2)运行以下程序,观察&a[0]、&a[i]和p的变化,然后回答以下问题:
① 程序的功能是什么?
② 在开始进入循环体之前,p指向谁?
③ 循环每增加一次,p的值(地址)增加多少?它指向谁?
④ 退出循环后,p指向谁?
⑤ 你是否初步掌握了通过指针变量引用数组元素的方法?
# include <stdio.h>
int main()
{
int i,*p,s=0,a[5]={5,6,7,8,9};
p=a;
for(i=0;i<5;i++,p++)
s+=*p;
printf("\n s=%d",s);
return 0;
}
(3)先分析以下程序的运行结果,然后上机验证,并通过此例掌握通过指针变量引用数组元素的各种方法。
# include <stdio.h>
int main( )
{
int i,s1=0, s2=0, s3=0, s4=0,*p,a[5]={1,2,3,4,5};
p=a;
for(i=0;i<5;i++)
s1+=p[i];
for(i=0;i<5;i++)
s2+=*(p+i); for(p=a;p<a+5;p++)
s3+=*p;
p=a;
for(i=0;i<5;i++)
s4+=*p++;
printf("\n s1=%d, s2=%d, s3=%d, s4=%d"s1,s2,s3,s4);
return 0;
}
(4)编写函数,将n个数按原来的顺序的逆序排列(要求用指针实现),然后编写主函数完成:
① 输入10个数。
② 调用此函数进行重排。
③ 输出重排后的结果。
分析与讨论
(1)指针的定义方法,指针和变量的关系。
(2)数组和指针的关系。
9. 实验项目:0521103009
实验名称:结构体及其应用
实验目的
(1)掌握结构体变量与结构体数组的定义和使用。
(2)学会使用结构体指针变量和结构体指针数组。
(3)掌握链表的概念,初步学会对链表进行操作。
实验内容
(1)输入10个学生的学号、姓名和成绩,求出其中的高分者和低分者。
#include <stdio.h>
struct student
{
int num;
char name[20];
int score;
};
int main( )
{
int i;
struct student st,stmax,stmin;
stmax.score=0; stmin.score=100;
printf("\n input data");
for(i=0;i<10;i++)
{
scanf("%d%s%d",&st.num,st.name,&st.score);
if(st.score>stmax.score)
stmax=st;
if(st.score<stmin.score)
stmin=st;
}
printf("\n hight:%5d%15s%5d",stmax.num,stmax.name,stmax.score);
printf("\n low:%5d%15s%5d",stmin.num,stmin.name,stmin.score);
return 0;
}
① 分析程序,上机运行程序。
② 程序中,哪些是对结构体变量成员的引用?哪些是整体引用?
③ 对于此例来说,用结构体变量作为数据结构有何优越性?
(2)有一学生情况如下表所示。编制一个C程序,用冒泡法对该学生情况表按成绩(grade)从低到高进行排序。
学号 |
姓名 |
性别 |
年龄 |
成绩 |
101 |
Zhang |
M |
19 |
95.6 |
102 |
Wang |
F |
18 |
92.2 |
103 |
Zhao |
M |
19 |
85.7 |
104 |
Li |
M |
20 |
96.3 |
105 |
Gao |
M |
19 |
90.2 |
106 |
Lin |
M |
18 |
91.2 |
107 |
Ma |
F |
18 |
98.7 |
108 |
Zhen |
M |
21 |
88.7 |
109 |
Xu |
M |
19 |
90.1 |
110 |
Mao |
F |
22 |
94.7 |
具体要求如下:
① 结构体类型为
struct student
{ int num;
char name[8];
char sex;
int age;
double grade;}
② 在程序中用一个结构体指针数组,其中每一个指针元素指向结构体类型的各元素。
③ 在程序中,首先输出排序前的学生情况,然后输出排序后的结果,其格式如上表所示。
(3)链表基本操作,具体要求如下:
① 初始时链表为空,即链表的头指针为空。
② 对于上表所示的学生情况,依次将每个学生的情况作为一个结点插入单链表的链头(即当前插入的结点将成为第一个结点)。
③ 所有学生情况都插入链表中后,从链头开始,依次输出链表中的各结点值(即每个学生的情况)。输出格式如同上表。
分析与讨论
(1)结构体的作用是什么?如何进行初始化?
(2)如何访问结构体中的成员?
(3)链表有什么优点?
10. 实验项目:0521103010
实验名称:文件
实验目的
(1)掌握文件与文件指针的概念。
(2)学会使用文件打开、文件关闭、读与写文件等基本的文件操作函数。
(3)运用文件操作函数进行程序设计。
实验内容
(1)以文本方式建立初始数据文件,请输入10个学生的学号、姓名及考试成绩,形式如下:
1001 LiLi 80
1002 HuWei 90
1003 LiMing 75
M
读入file1.dat中的数据,找出最高分和最低分的学生。
#include <stdio.h>
struct student
{ int num;
char name[20];
int score;};
int main()
{ int i;
student st,stmax,stmin;
FILE *fp;
stmax.score=0; stmin.score=100;
fp=fopen("file1.dat","r");
if(!fp) return 1;
for(i=0;i<10;i++)
{ fscanf(fp,"%d%s%d",&st.num,st.name,&st.score);
if(st.score>stmax.score)
stmax=st;
if(st.score<stmin.score)
stmin=st; }
fclose(fp);
printf(" hight:%5d%15s%5d",stmax.num,stmax.name,stmax.score);
printf("\n low:%5d%15s%5d",stmin.num,stmin.name,stmin.score);
return 0;}
① 分析程序,上机运行程序并分析运行结果。
② 如果事先不知道学生个数,则程序应该如何修改?请将以上程序中的循环语句for(i=0;i<10;i++)改为(while(!feof(fp)),再运行程序,看结果是否正确?
(2)读入file2.dat中的数据,然后按成绩从高到低的顺序进行排序,并将排序结果分别以文本方式存入文件file3.dat中,以二进制形式存入文件file4.dat中。
#include <stdio.h>
struct student
{ int num; char name[20]; int score;};
void sort(struct student *,int);
int main()
{ int i,n=10;
struct student st[10];
FILE *fp,*fp1,*fp2;
fp=fopen("file2.dat","r");
if(!fp) return 1;
for(i=0;i<10;i++)
fscanf(fp,"%4d%10s%3d",&st[i].num,st[i].name,&st[i].score);
fclose(fp);
sort(st,n);
fp1=fopen("file3.dat","w");
for(i=0;i<n;i++)
fprintf(fp1, "%4d%10s%3d",st[i].num,st[i].name,st[i].score);
fclose(fp1);
fp2=fopen("file4.dat","wb");
fwrite(st,sizeof(struct student),n,fp2);
fclose(fp2);
return 0;
}
void sort(struct student *st,int n)
{
struct student *i,*j,t;
for(i=st;i<st+n-1;i++)
for(j=i+1;j<st+n;j++)
if(i->score<j->score)
{ t=*i; *i=*j; *j=t; } }
请分析程序,上机运行程序,运行结果在哪里?与上一例相比,此例中对读取文件的格式有何不同?
(3)某班有学生145人,每人的信息包括:学号、姓名、性别和成绩。编制一个C程序,完成以下操作:
① 定义一个结构体类型数组。
② 打开可读写的新文件student.dat。
③ 使用函数fwrite将结构体数组内容写入文件student.dat中。
④ 关闭文件student.dat。
⑤ 打开可读写文件student.dat。
⑥ 从文件中依次读出各学生情况并按学生成绩进行排序,输出排好序后的数据。
⑦ 关闭文件student.dat。
分析与讨论
(1)文件有哪些优点?
(2)文件常用的读写操作函数有什么不同?
(3)调试有关文件的程序要注意什么?
五、实验课考核方式
1. 实验报告:主要内容包括实验目的、实验内容、实验步骤和结果,给出相应的分析过程,对实验结果客观分析.要求格式规范,书写整齐.
2. 实验课的考核方式和成绩评定办法:根据学生提交的实验报告的质量和学生平时实验过程中的表现情况综合给分.
六、实验指导书以及主要参考书
[1] 李含光,郑关胜.C语言程序设计教程(第2版).清华大学出版社.2015.
[2] 谭浩强.C程序设计(第四版).清华大学出版社.2014.
[3] 谭浩强.C程序设计题解与上机指导(第四版).清华大学出版社.2014.