c语言实验
一、课程性质和任务
本课程的主要任务:通过对该课程的学习,使学生掌握C语言程序设计的基本知识,程序结构,基本算法及程序设计思想,并培养使用C语言进行程序设计基本能力。
本课程的目的:使学生掌握程序设计的基本方法及逐步形成正确的程序设计思想,能够熟练地使用C语言进行程序设计并具备调试程序的能力,为后继课程及其他程序设计课程的学习和应用打下基础。
二、课程教学目标
1、掌握C语言的基本词法,熟练掌握C语言程序的基本结构。
2、掌握常量和变量的存储类型及应用;运算符和表达式的应用
3、掌握C语言的基本语句;形成正确的程序设计思想,对顺序结构程序要重点掌握,熟练掌握输入输出函数。
4、掌握关系、逻辑表达式的形式和应用;熟练掌握选择结构的思想;掌握IF语句的各种形式和应用;掌握SWITCH语句和BREAK语句的使用,选择结构的嵌套语句。
5、掌握循环结构的思想、流程和执行过程;掌握 While循环、Do…While、FOR循环及其应用;掌握循环嵌套的使用;掌握BREAK、CONTINUE及使用。
6、掌握一维数组的定义、引用和应用;掌握二维数组的定义、引用和应用;掌握字符数组及其应用。
7、掌握函数的定义、参数、类型、返回值及参数传递;掌握变量的作用域(局部变量和全局变量)、存储类型;了解内部函数和外部函数及主函数和命令行参数。
9、掌握直接存取和间接存取;掌握指针变量的概念和应用;掌握数组与指针、函数与指针之间的关系;了解指向指针的指针。
10、掌握结构体、共用体的概念、存储特点,及应用;了解结构体数组的使用;掌握结构体与数组、指针、函数之间的操作;掌握链表的概念和基本操作。了解共用体、自定义类型、枚举类型的概念和应用。
三、实验内容安排
实验1:熟悉上机环境和顺序结构编程练习
[实验目的]
1. 熟练地利用文本编辑程序输入、修改C程序。
2. 掌握和理解C程序的基本结构。
3. 掌握C程序的编译连接与运行。
4. 掌握和理解本实验中出现的一些最基本的语句。
[实验内容]
1. 键盘输入与屏幕输出练习
问题1 要使下面程序的输出语句在屏幕上显示1, 2, 34,则从键盘输入的数据格式应为以下备选答案中的 。
#include <stdio.h>
main()
{
char a,b;
int c;
scanf("%c%c%d",&a,&b,&c);
printf("%c,%c,%d\n",a,b,c);
}
A)1 2 34 B)1, 2, 34
C)’1’,’2’,34 D)12 34
问题2 在与上面程序的键盘输入相同的情况下,要使上面程序的输出语句在屏幕上显示1 2 34,则应修改程序中的哪条语句?怎样修改?
问题3 要使上面程序的键盘输入数据格式为1,2,34,输出语句在屏幕上显示的结果也为1,2,34,则应修改程序中的哪条语句?怎样修改?
问题4 要使上面程序的键盘输入数据格式为1,2,34,而输出语句在屏幕上显示的结果为'1', '2',34,则应修改程序中的哪条语句?怎样修改?
[提示:利用转义字符输出字符单引号字符。]
2. 计算定期存款本利之和
设银行定期存款的年利率rate为2.25%,并已知存款期为n年,存款本金为capital元,试编程计算n年后的本利之和deposit。要求定期存款的年利率rate、存款期n和存款本金capital均由键盘输入。
公式:deposit=capital*(1+rate*n)
deposit=capital*(1+rate)n
实验2:选择结构程序设计
[实验目的]
1. 进一步掌握各种表达式的使用。
2. 利用if语句实现选择结构。
3. 利用switch语句实现多分支选择结构。
4. 练习调试与修改程序,
[实验内容]
1. 计算下列分段函数值:
x (x<1)
y= 2x-1 (1≤x≤10)
3x-11 (x≧10)
具体要求如下:
(1) 用if语句实现分支。自变量x与函数值均用双精度类型。
(2) 自变量x用scanf函数输入,且输入前要有提示。结果的输出采用以下形式:
x= 具体值 ,f(x)= 具体值
2、身高预测
每个做父母的都关心自己孩子成人后的身高,据有关生理卫生知识与数理统计分析表明,影响小孩成人后的身高的因素包括遗传、饮食习惯与体育锻炼等。小孩成人后的身高与其父母的身高和自身的性别密切相关。
设faHeight为其父身高,moHeight为其母身高,身高预测公式为
男性成人时身高=(faHeight + moHeight)×0.54cm
女性成人时身高=(faHeight×0.923 + moHeight)/2cm
此外,如果喜爱体育锻炼,那么可增加身高2%;如果有良好的卫生饮食习惯,那么可增加身高1.5%。
编程从键盘输入用户的性别(用字符型变量sex存储,输入字符F表示女性,输入字符M表示男性)、父母身高(用实型变量存储,faHeight为其父身高,moHeight为其母身高)、是否喜爱体育锻炼(用字符型变量sports存储,输入字符Y表示喜爱,输入字符N表示不喜爱)、是否有良好的饮食习惯等条件(用字符型变量diet存储,输入字符Y表示良好,输入字符N表示不好),利用给定公式和身高预测方法对身高进行预测。
3、 简单的计算器
用switch语句编程设计一个简单的计算器程序,要求根据用户从键盘输入的表达式:
操作数1 运算符op 操作数2
计算表达式的值,指定的算术运算符为加(+)、减(-)、乘(*)、除(/)。
本实验程序是在例4.8的基础上,增加如下要求:
(1)如果要求程序能进行浮点数的算术运算,程序应该如何修改?如何比较实型变量data2和常数0是否相等?
(2)如果要求输入的算术表达式中的操作数和运算符之间可以加入任意多个空白符,那么程序如何修改?
(3)(选作题)如果要求连续做多次算术运算,每次运算结束后,程序都给出提示:
Do you want to continue(Y/N or y/n)?
用户输入Y或y时,程序继续进行其他算术运算;否则程序退出运行状态。那么,程序如何修改?
实验三:循环结构的程序设计
[实验目的]
1.进一步练习选择结构的程序设计。
2.练习并掌握实现循环结构的三种方法。
3.练习并掌握选择结构与循环结构的嵌套。
4.练习调试与修改程序。
[实验内容]
1. 求1-2+3-4+5……+99-100的值。
2. 计算下列级数和
s=1-(1/3)+(1/5)-(1/7)+…+(-1)n(1/(2n+1))直到最后一项的绝对值小于10-4为止。
要求输出s和总的项数n。输出形式为 n=具体值,s=具体值
3. 猜数游戏
在这个实验中,我们将尝试编写一个猜数游戏程序,这个程序看上去有些难度,但是如果按下列要求循序渐进地编程实现,会发现其实这个程序是很容易实现的。那么,现在就开始吧,先编写第1个程序,然后试着在第1个程序的基础上编写第2个程序,……
程序1 编程先由计算机“想”一个1~100之间的数请人猜,如果人猜对了,则计算机给出提示“Right!”,否则提示“Wrong!”,并告诉人所猜的数是大(Too high)还是小(Too low),然后结束游戏。要求每次运行程序时机器所“想”的数不能都一样。
程序2 编程先由计算机“想”一个1~100之间的数请人猜,如果人猜对了,则结束游戏,并在屏幕上输出人猜了多少次才猜对此数,以此来反映猜数者“猜”的水平;否则计算机给出提示,告诉人所猜的数是太大还是太小,直到人猜对为止。
程序3 编程先由计算机“想”一个1~100之间的数请人猜,如果人猜对了,则结束游戏,并在屏幕上输出人猜了多少次才猜对此数,以此来反映猜数者“猜”的水平;否则计算机给出提示,告诉人所猜的数是太大还是太小,最多可以猜10次,如果猜了10次仍未猜中的话,结束游戏。
程序4 编程先由计算机“想”一个1~100之间的数请人猜,如果人猜对了,在屏幕上输出人猜了多少次才猜对此数,以此来反映猜数者“猜”的水平,则结束游戏;否则计算机给出提示,告诉人所猜的数是太大还是太小,最多可以猜10次,如果猜了10次仍未猜中的话,则停止本次猜数,然后继续猜下一个数。每次运行程序可以反复猜多个数,直到操作者想停止时才结束。
实验四:一维数组
[实验目的]
1. 清楚一维数组定义格式及下标范围。
2. 学习利用数组解决简单应用问题。
3. 进一步熟悉条件控制和循环控制。
4. 通过二维数组的应用学会二重循环的程序设计。
[实验内容]
1. 下面的程序重新安排数组a 中的元素,请读懂这个程序:
#include <stdio.h>
main()
{
int a[]={2,3,-3,-5,6,-1,9,8,7,-7,-6,11};
int size=12;
int i=-1,j=size,d,k;
while(++i< --j)
{
while(i<j&&a[i]>0) i++;
while(i<j&&a[j]<0) j--;
if(i<j)
{
d=a[i];
a[i]=a[j];
a[j]=d;
}
}
for(k=0;k<size;k++) printf(″%d″,a[k]);
}
2. 编写一个程序,从键盘输入10个学生的成绩,统计最高分`最低分和平均分。
[要求]
输入的数据首先存入一个数组中,程序中不得改变数组中这些数据的排列顺序;
运行时输入下列数据并记录程序的输出结果:
82 90 88 78 63 75 94 86 99 71
3. 思考题
已有一个已排好序的数组,今输入一个数,要求按原来排序的规律将它插入数组中。
实验五:二维数组
1. 检验并打印魔方矩阵
在下面的5×5阶魔方矩阵中,每一行、每一列、每一对角线上的元素之和都是相等的,试编写程序将这些魔方矩阵中的元素读到一个二维整型数组中,然后检验其是否为魔方矩阵,并将其按如下格式显示到屏幕上。
2. 餐饮服务质量调查打分
在商业和科学研究中,人们经常需要对数据进行分析并将结果以直方图的形式显示出来。例如,一个公司的主管可能需要了解一年来公司的营业状况,比较一下各月份的销售收入状况。如果仅给出一大堆数据,这显然太不直观了,如果能将这些数据以条形图(直方图)的形式表示,将会大大增加这些数据的直观性,也便于数据的分析与对比。下面以顾客对餐饮服务打分为例,练习这方面的程序编写方法。假设有40个学生被邀请来给自助餐厅的食品和服务质量打分,分数划分为1~10这10个等级(1表示最低分,10表示最高分),试统计调查结果,并用*打印出如下形式的统计结果直方图。
Grade Count Histogram
1 5 *****
2 10 **********
3 7 *******
...
3. 通过赋初值按行顺序给2*3的二维数组赋予2,4,6等偶数,然后按列的顺序输出该数组,即输出其转置矩阵。
实验六:使用函数的程序设计
[实验目的]
1. 掌握函数定义和调用方法。
2. 掌握函数递归调用的方法。
3. 理解变量的作用域和生存期。
[实验内容与要求]
1. 分析程序运行结果
(1)#include <stdio.h>
int n;
int f(int x);
main()
{
int a,b;
a=5;
b=f(a); /*判断输出 实际输出*/
printf(”\n局部 a=%d”,a); /* ( ) ( )*/
printf(”\n局部 b=%d”,b); /* ( ) ( )*/
printf(”\n全局 n=%d\n”,n); /* ( ) ( )*/
a++;
b=f(a);
printf(”\n局部 a=%d”,a); /* ( ) ( )*/
printf(”\n局部 b=%d”,b); /* ( ) ( )*/
printf(”\n全局 n=%d\n”,n); /* ( ) ( )*/
}
int f(int x)
{
int a=1;
static int b; /*判断输出 实际输出*/
a++;b++;x++;n++; /*第一次 第二次 第一次 第二次*/
printf(”\n局部 fa=%d”,a); /* ( ) ( ) ( ) ( )*/
printf(”\n局部 fb=%d”,b); /* ( ) ( ) ( ) ( )*/
printf(”\n 叁数 x=%d\n”,x); /*( ) ( ) ( ) ( )*/
return x;
}
[要求]
a.读程序,判断程序的输出并填入相应行行尾的”判断输出”栏目下;
b.实际运行程序,记录程序的输出, 并填入相应行行尾的”实际输出”栏目下;
c.对比判断输出和实际输出,如有不符,分析产生错误判断的原因。
(2)#include <stdio.h>
main()
{
void fun(int n);
fun(3);
}
void fun(int n)
{
if(n<=1) printf(“a”);
else {
fun(n-1);
printf(“b”);
fun(n-2);
printf(“c”);
}
}
[要求]
a.读程序,判断程序的输出;
b.实际运行程序,记录程序的输出;
c.对比判断输出和实际输出,如有不符,分析产生错误判断的原因。
2. 写一个判素数的函数,在主函数输入一个整数,输出是否素数的信息。
3. 计算并输出
m!
(m-n)! n!
[具体要求]
1. 编制一个函数p(n),返回n!值.
2. 编制主函数,由键盘输入m与n(m≧n≧0).调用(1)中的函数计算的值。
m!
(m-n)! n!
实验七 使用指针的程序设计
[实验目的]
1. 进一步练习模块化设计的方法。
2. 掌握使用指针变量的程序设计。
3. 掌握字符串的指针表示方法。
[实验内容]
1.下面是一个涉及到一系列指针操作的程序:
#include <stdio.h>
main()
{
int m[]={0,1,2,3,4,5,6,7,8,9}; /*判断输出 实际输出*/
int p =m+3;
printf(“%d\n”,*p); /*( ) ( )*/
printf(“%d\n”,++*p); /*( ) ( )*/
printf(“%d\n”,*p); /*( ) ( )*/
printf(“%d\n”,*++p); /*( ) ( )*/
printf(“%d\n”,*p); /*( ) ( )*/
printf(“%d\n”,*p++); /*( ) ( )*/
printf(“%d\n”,*p); /*( ) ( )*/
printf(“%d\n”,(*p)++); /*( ) ( )*/
printf(“%d\n”,*p); /*( ) ( )*/
printf(“%d\n”,++*p++); /*( ) ( )*/
printf(“%d\n”,*p); /*( ) ( )*/
printf(“%d\n”,++*p++); /*( ) ( )*/
printf(“%d\n”,*p); /*( ) ( )*/
}
[要求]
(1)读程序,判断程序的输出并填入相应行行尾的”判断输出”栏目下;
(2)实际运行程序,记录程序的输出, 并填入相应行行尾的”实际输出”栏目下;
(3)对比判断输出和实际输出,如有不符,分析产生错误判断的原因。
2.打印最高分和学号
假设每班人数最多不超过40人,具体人数由键盘输入,试编程打印最高分及其学号。
程序1 用一维数组和指针变量作为函数参数,编程打印某班一门课成绩的最高分及其学号。
程序2 用二维数组和指针变量作为函数参数,编程打印3个班学生(假设每班4个学生)的某门课成绩的最高分,并指出具有该最高分成绩的学生是第几个班的第几个学生。
程序3 用指向二维数组第0行第0列元素的指针作为函数参数,编写一个计算任意m行n列二维数组中元素的最大值,并指出其所在的行列下标值的函数,利用该函数计算3个班学生(假设每班4个学生)的某门课成绩的最高分,并指出具有该最高分成绩的学生是第几个班的第几个学生。
程序4 编写一个计算任意m行n列二维数组中元素的最大值,并指出其所在的行列下标值的函数,利用该函数和动态内存分配方法,计算任意m个班、每班n个学生的某门课成绩的最高分,并指出具有该最高分成绩的学生是第几个班的第几个学生。
【思考题】 请读者思考:
编写一个能计算任意m行n列的二维数组中的最大值,并指出其所在的行列下标值的函数,能否使用二维数组或者指向二维数组的行指针作为函数参数进行编程实现呢?为什么?
实验八结构应用程序设计
[实验目的]
1. 掌握定义结构类型的方法。
2. 掌握结构变量的定义和初始化方法。
3. 掌握直接访问(通过.)和间接访问(通过->)结构成员的方法。
4. 熟悉结构数据处理的一些基本技巧.
[实验内容]
1. 函数sortbyage对一个staff(职工)数组按年龄由小到大的顺序进行排序,排序采用插入法,排序结果记录在另一个数组中.下面给出了结构类型和主函数及一个输出函数。请完成sortbyage()函数的设计。
struct staff{
char staffno[5];
char name[10];
char sex[3];
int age;
};
void sortbyage(staff a[],staff *b[],int n)
{
/* 函数体请自已完成 */
}
void showstaff(staff a)
{
printf(“\n%5c%9c%3c%4d\n”,a.staffno,a.name,a.sex.a.age);
}
main()
{ staff a[]={
{“0751”,”陈洁”,”女”,34},
{“0682”,”赵仙”,”男”,28},
{“0853”,”郑玲”,”女”,22},
{“0852”,”屈进”,”男”,56},
{“0781”,”赵宁”,”男”,47},
{“0752”,”张建”,”男”,23},
{“0691”,”李芬”,”女”,25},
{“0934”,”花季”,”女”,19},
{“0931”,”金全”,”男”,44},
{“0932”,”王利”,”男”,37},
};
staff *b[10];
int i;
sortbyage(a,b,10);
for(i=0;i<10;i++) showstaff(*b[i]);
}
2. 在屏幕上模拟显示一个数字式时钟
按如下方法定义一个时钟结构体类型:
struct clock
{
int hour;
int minute;
int second;
};
typedef struct clock CLOCK;
然后,将下列用全局变量编写的时钟模拟显示程序改成用CLOCK结构体变量类型重新编写。已知用全局变量编写的时钟模拟显示程序如下:
#include <stdio.h>
#include <stdio.h>
int hour, minute, second; /*全局变量定义*/
/*
函数功能:时、分、秒时间的更新
函数参数:无
函数返回值:无
*/
void Update(void)
{
second++;
if (second == 60) /*若second值为60,表示已过1分钟,则 minute值加1*/
{
second = 0;
minute++;
}
if (minute == 60) /*若minute值为60,表示已过1小时,则 hour值加1*/
{
minute = 0;
hour++;
}
if (hour == 24) /*若hour值为24,则hour的值从0开始计时*/
{
hour = 0;
}
}
/*函数功能:时、分、秒时间的显示
函数参数:无
函数返回值:无
*/
void Display(void) /*用回车符'\r'控制时、分、秒显示的位置*/
{
printf("%2d:%2d:%2d\r", hour, minute, second);
}
/*函数功能:模拟延迟1秒的时间
函数参数:无
函数返回值:无
*/
void Delay(void)
{
long t;
for (t=0; t<50000000; t++)
{
/*循环体为空语句的循环,起延时作用*/
}
}
main()
{
long i;
hour = minute = second = 0;/*hour,minute,second赋初值0*/
for (i=0; i<100000; i++)/*利用循环结构,控制时钟运行的时间*/
{
Update(); /*时钟更新*/
Display(); /*时间显示*/
Delay(); /*模拟延时1秒*/
}
}
【思考题】 请读者思考:
请读者自己分析下面两段程序代码,并解释它们是如何实现时钟值更新操作的。
void Update(struct clock *t)
{
static long m = 1;
t->hour = m / 3600;
t->minute = (m – 3600 * t->hour) / 60;
t->second = m % 60;
m++;
if (t->hour == 24)
{
m = 1;
}
}
void Update(struct clock *t)
{
static long m = 1;
t->second = m % 60;
t->minute = (m / 60) % 60;
t->hour = (m / 3600) % 24;
m++;
if (t->hour == 24)
{
m = 1;
}
}