计算机程序设计基础实验指导
实验一 C语言程序的运行环境和运行过程
1.1 实验目的与要求
1. 了解C语言在VC6.0编程环境下的操作,熟悉常用的功能菜单命令。 2. 通过运行简单的C程序,初步了解C源程序的特点。
1.2 实验内容
1.2.1 Microsoft Visual C++6.0(简称VC++6.0或VC6.0)的简介和安装
如果计算机中未安装VisualC++6.0,则应先安装VisualC++6.0。Visual C++是Microsoft Visual Studio的一部分,因此需要找到Visual Studio的光盘,执行其中的setup.exe,并按照屏幕上的提示进行安装即可。
下面详细介绍如何用VisualC++6.0开发工具来编辑、编译、连接和执行一个C程序。 1. 进入C的工作环境
在windows环境下,选择“开始”→“程序”→Microsoft Visual Studio→VisualC++6.0(也可以从桌面快捷方式进入)即可。屏幕上出现VisualC++6.0的主窗口,如图1-1所示。在VisualC++6.0主窗口的顶部是VisualC++的主菜单栏,其中包括9个菜单项:File(文件)、Edit(编辑)、Insert(插入)、Project(项目)、Build(构建)、Tools(工具)、Window(窗口)、Help(帮助)。以上各项在括号中的是VC6.0中文版中的中文显示。
程序编辑窗口:用来输入和编辑源程序
项目工作区:显示所设定的工作区的信息
调试信息窗口:用来显示程序出错信息和结果有无错误(errors)或警告( warinings)。
图1-1 VisualC++6.0主窗口
2. 新建一个C语言源程序(介绍比较简单的情况,即程序只由一个源程序文件组成,即单文件程序。我们平时
学习二级C语言一般都是单文件程序)
在Visual C++主窗口的主菜单栏中单击File(文件),在其下拉菜单中单击New(新建),如图1-2所示。
1
图1-2 单击New(新建)
弹出一个对话框,单击此对话框的左上角的File(文件)选项卡,选择C++Source File选项,如图1-3所示。
图1-3 给程序命名
右边的“File(文件)”栏可以输入文件名,“C 目录”栏可以设定文件保存的路径和地址,我们在右上方的File(文件)文本框输入准备编辑的源程序文件的名字(如first.c)。
注意:如果不写后缀,系统会默认指定为.cpp,表示要建立的是C++源程序。因此命名时必须要加上后缀.c 。 单击“确定”(OK)按钮后,如图1-4所示,就可以输入程序代码了。
2
图1-4开始输入程序代码
我们输入的程序代码如下(其中有两处错误): #include\"stdio.h\" main( ); {
printf(“Hello!\\n\") }
3. 编译和调试程序 (1) 程序编译
单击主菜单栏中的Build(编译),在其下拉菜单中选择Compile first.c(编译first.c)项,如图1-5所示。
图1-5编译程序
3
单击Compile first.c(编译first.c)命令后,屏幕上出现一个对话框,如图1-6所示。(此编译命令要求一个有效的项目工作区,你是否同意建立一个默认的项目工作区?)单击是(Y)按钮,表示同意由系统建立默认的项目工作区。
图1-6要求建立默认的项目工作区
屏幕如果继续出现“将改动保存到D:\\first.c”,单击“是”。
屏幕下面的调试信息窗口指出源程序有无错误,本例显示2 error(s),0 warning(s)。 (2) 程序调试
发现和改正程序中的错误。需要初学者注意的是,程序有时会出现错误(errors)和几个警告(warnings)性信息。
(warnings),警告不影响程序执行,只有致命性错误(errors)才影响。本例显示如图1-7所示。
图1-7调试信息窗口指示程序有无错误 用鼠标拖动调试信息窗口中右侧的滚动条,可以看到出错的位置和性质。 (3) 进行改错
双击调试信息窗口中的第1个报错行,这时在程序窗口中出现一粗箭头指向被报错的程序行(第3行),提示改错位置,如图1-8所示。找到错误是第2行末尾的分号,我们将第2行末尾的分号删去。
4
图1-8提示改错位置
(4) 再重新编译
每修改一个错误之后,再一次编译,即单击主菜单栏中的Build(编译),在其下拉菜单中选择Compile first.c(编译first.c)项。然后再一次找到第1个出错位置在第4行末尾没有分号,我们在第4行末尾加上分号。
最后再选择compile first.c项重新编译,此时编译信息告诉我们:0 error(s),0 warning(s) (如图1-9),表示编译成功。这时产生一个first.obj文件。
图1-9产生目标文件
5
4. 连接程序
选择主菜单Build(编译)→Build first.exe(构建first.exe),成功完成连接后,生成了一个可执行文件first.exe。
以上我们是分别进行程序的编译和连接,其实我们可以选择菜单Build→Build(或按F7键)一次完成编译和连接。但对于初学者,我们还是提倡分步进行编译和连接。 5. 执行程序
选择Build→!Execute first.exe(执行first.exe)(或按Ctrl+F5运行也可)。屏幕上出现输出结果的窗口,显示出运行结果,如图1-10所示。可以看到“Hello!”。
图1-10显示运行结果
6. 关闭工作区
这个C程序完成后,选择File(文件)→Close Workspace(关闭工作区),屏幕提示如图1-11所示。单击是”关闭工作区以结束对该程序的操作,然后又可以写新程序了。
有的初学者在编辑了多个程序后,发现运行的结果还是第一个程序,就是没有关闭工作区造成的。
图1-11确认是否关闭所有工作区
7. 打开已经保存的文件
方法一:选择File(文件)→Open(打开)菜单或按Ctrl+O键,或单击工具栏中的Open小图标来打开Open对话框,从中选择所需的文件,打开该文件。
方法二:如果后缀为.c的文件与VC6.0建立的关联,在Windows“资源管理器”或“我的电脑”中按路径找到已有的C程序名(如在D:\\文件夹下面找到first.c)。双击此文件名,则自动进入了VC6.0集成环境,并打开了该文件。 8. 保存文件
如果保存在原来的文件中,可以选择File(文件)→Save(保存),或用Ctrl+S快捷键或单击工具栏中的小图标来保存文件。
如果不想将源程序存放到原先指定的文件中,可以选择Save As(另存为)项,并在弹出的Save As对话框中指定文件路径和文件名。
相应的快捷键如下:
Compile (编译)――>Ctrl+F7 Build (构建)――>F7
Execute (执行)――>Ctrl+F5
1.2.2典型例题分析
【例1.1】在VC中输入以下求矩形面积的程序,其中有两错误,运行并调试如下程序: #include\"stdio.h\"
6
main( ) {
int a,b,s; a=3 b=7; s=a*b
printf(\"a=%d,b=%d,c=%d\\n\}
按照上面介绍的步骤,新建一个C源程序,输入该程序代码。 然后编译,假如有致命性错误(errors),根据信息窗口的提示分别予以纠正。在程序修改后,再进行编译,如果还有错,反复调试编译直到正确,用“编译”菜单中的“执行”菜单项(或快捷键【Ctrl】+【F5】)执行程序。
最后关闭工作区。
图1-12例1.1运行的结果
1.2.3 实验题目
1. 在VC中输入以下的程序,运行并查看运行结果:
#include\"stdio.h\"
main( ) {
printf(\"How are you! \");
printf(\"I’m fine, thank you!and you? \"); }
多运行几遍,看看运行结果,将printf(\"How are you ! \")改成printf(\"How are you!\\n\"),再运行几遍,看看运行结果,比较一下有什么不同,想想为什么。 2. 编写一个c程序,输出以下信息:
**************** Very good!
****************
7
实验二 数据类型、运算符与表达式及顺序结构程序设
计
2.1 实验目的与要求
1. 2. 3. 4. 5.
掌握C语言数据类型,熟悉如何定义一个整型、字符型和实型的变量。 掌握C语言各种类型的常量
掌握不同数据类型之间赋值的规律。
掌握C的有关算术运算符,以及包含这些运算符的表达式的求值规则, 熟悉顺序结构,掌握printf( )和scanf( )函数。
2.2 实验内容
2.2.1典型例题分析
【例2.1】分析下列程序,并上机运行。 #include\"stdio.h\" main() {
long x,y; int a,b,c,d; x=5; y=6; a=7; b=8; c=x+a; d=y+b;
printf(\"c=x+a=%d,d=y+b=%d\\n\}
运行此程序的结果:(见图2-1)
图2-1 例2.1的运行结果 【例2.2】分析下列程序,并上机运行。 #include\"stdio.h\" main() {
int a,b,c;
8
a=5;b=6;c=7;
printf(“ ab c\de\\rf\\n”); printf(“hijk\L\\bM\\n”); }
运行此程序的结果:(见图2-2)
图2-2 例2.2的运行结果 【例2.3】分析下列程序,并上机运行。 #include \"stdio.h\" void main( ) {
int i,j,m,n; i=2; j=5; m=++i; n=j++;
printf(\"%d,%d,%d,%d\\n\}
运行此程序的结果:(见图2-3)
图2-3 例2.3的运行结果 【例2.4】分析下列程序,并上机运行。 #include\"stdio.h\" main() {
char c1,c2; c1='a';c2='b'; c1=c1-32;c2=c2-32;
printf(\"%c %c\\n \}
运行此程序的结果:(见图2-4)
9
图2-4 例2.4的运行结果
【例2.5】分析下列程序,并上机运行。 #include\"stdio.h\" main() {
int a=97,b=98;
printf(\"%d %d\\n\ printf(\"%d,%d\\n\ printf(\"%c,%c\\n\ printf(\"a=%d,b=%d\}
运行此程序的结果:(见图2-5)
图2-5 例2.5的运行结果
【例2.6】用下面的 scanf 函数输入数据,使 i=40,j=78,k=56.89,m=2.3,c1=′R′,c2=′T′。问在键盘上如何输入?
#include \"stdio.h\" void main () {
int i,j; float k,m; char c1,c2;
scanf(\"i=%d**j=%d\scanf(\"%f##%f\scanf(\"%c,%c\
printf(\"i=%d,j=%d,k=%f,m=%f,c1=%c,c2=%c \}
答:输入:i=40**j=78回车 56.89##2.3R,T回车
2.2.2 程序调试
1. 分析下列程序,并上机运行
#include\"stdio.h\" main( )
10
请
{
int a,b,d=25;
a=d/10%9;b=a&&(-1); printf(\"%d,%d\\n\
}
2. 分析下列程序,并上机运行
#include\"stdio.h\" main( ) {
int a,b,c; a=10; b=20;
c=(a%b<1)‖(a/b>1);
printf(\"a=%d b=%d c=%d\\n\}
3. 分析下列程序,并上机运行
#include\"stdio.h\" main() {
char c='A';
int i=1,j=2,k=3; float x=3e+5,y=0.85;
printf(\"%d,%d\\n\
printf(\"%d,%d\\n\
printf(\"%d,%d\\n\}
运行结果为: 。 4. 分析下列程序,并上机运行
#include\"stdio.h\" main( ) {
float k;
float x=3.5,y=2.5; int a=2,b=4;
k=(float)(a+b)/2+(int)x%(int)y; printf(\"%f\}
运行结果为: 。
2.2.3 实验题目
1. 编写一个程序,输入两个整数:2000和425,求出它们的商数和余数,并进行输出。
2. 编写程序,读入3个双精度数,求它们的平均值并保留此平均值小数点后一位数(对小数点后第2位数进行
四舍五入),最后输出结果。
3. 输入一个摄氏温度,要求输出华氏温度。公式为f=5/9*c+32。 4. 输入三个小写字母,输出其ASCII码和对应的大写字母。
5. 输入三角形的三边长,求三角形面积。已知三角形的三边长a,b,c,则该三角形的面积公式为:
areas(sa)(sb)(sc),其中s=(a+b+c)/2。
11
实验三 选择结构程序设计
3.1实验目的与要求
1. 2. 3. 4.
学会正确使用逻辑运算符和逻辑表达式的方法。 掌握程序的书写风格; 熟练掌握if语句的使用;
熟练掌握switch语句的使用。
3.2 实验内容
3.2.1 典型例题分析
【例3.1】编程实现,判别从键盘输入的一个字符是控制字符、数字、大写字母和小写字母中的哪一种。例如输入为“g”,则输出显示它为小写字符。
分析:可以根据输入字符的ASCII码来判别类型。由ASCII码表可知ASCII值小于32的为控制字符。在字符“0”和“9”之间的为数字,在字符“A”和“Z”之间为大写字母,在字符“a”和“z”之间为小写字母,其余则为其它字符。这是一个多分支选择的问题,所以用if-else-if语句编程,根据输入字符ASCII码所在的范围,分别给出不同的输出。
源程序代码:
#include\"stdio.h\" main() {
char c;
printf(\"input a character: \"); c=getchar();
if(c<32) //判断输入字符的ASCII值是否小于32 printf(\"This is a control character\\n\");
else if(c>='0'&&c<='9') //判断输入的字符是否在字符“0”和“9”之间 printf(\"This is a digit\\n\");
else if(c>='A'&&c<='Z') //判断输入的字符在字符“A”和“Z”之间 printf(\"This is a capital letter\\n\");
else if(c>='a'&&c<='z') //判断输入的字符在字符“a”和“z”之间 printf(\"This is a small letter\\n\");
else //判断输入的字符是否其它字符 printf(\"This is an other character\\n\"); }
程序运行结果:
例3.1 的程序运行结果
12
3.2.2 程序调试
1. 分析并运行以下程序
#include\"stdio.h\" main( ) {
int x, y;
printf(\"Enter x&y:\\n\"); scanf(\"%d%d\
printf(\"x, y: %d %d\\n\ if(x>y) printf(\"x=%d\\n\ if(y>x) printf(\"y=%d\\n\
if(x==y) printf(\"x==y%d:\\n\}
若运行时输入 3 5↵ ,则运行结果为: 。 2. 分析并运行以下程序
#include”stdio.h” main( ) {
int a,b,c, t;
printf(\"input a, b, c: \"); scanf(\"%d%d%d\
printf(\"a=%d,b=%d,c=%d\\n\ if(a>b)
{t=a; a=b;b=t;}
if(a>c)
{t=a; a=c; c=t;} if(b>c)
{t=b; b=c; c=t;}
printf(\"%d, %d, %d\\n\}
若运行时输入 8 9 7↵ ,则运行结果为: 。 3. 分析并运行以下程序
#include”stdio.h” main( ) {
int x,y;
printf(\"Enter x&y: \"); scanf(\"%d%d\
printf(\"x,y:%d%d\\n\ if(x>y)
printf(\"max=x=%d\\n\else
printf(\"max=y=%d\\n\ printf(\"**end**\\n\"); }
若运行时输入 9 7↵ ,则运行结果为: 。
13
4. 输入并运行以下程序
#include”stdio.h” main( ) {
int n;
printf(\"input n: \"); scanf(\"%d\ if(n%3==0)
printf(\"n=%d YES\\n\else
printf(\"n=%d NO\\n\
}
若运行时输入 8 ↵ ,则运行结果为: 。 5. 输入并运行以下程序
#include”stdio.h” main( ) {
int g;
printf(\"Enter a mark: \"); scanf(\"%d\ printf(\"g=%d: \ switch(g/10) {
case 10:
case 9: printf(\"A\\n\"); break; case 8: printf(\"B\\n\"); break; case 7: printf(\"C\\n\"); break; case 6: printf(\"D\\n\"); break; default : printf(\"E\\n\"); } }
若运行时输入 85 ↵ ,则运行结果为: 。
去掉每一句话后面的break语句,看看运行结果有什么不同。 6. 输入并运行以下程序
#include\"stdio.h\" main ( ) {
int x=1,y=0,a=0,b=0; switch(x)
{
case 1:switch (y)
{
case 0 : a++ ; break ; case 1 : b++ ; break ; }
case 2:a++; b++; break;
14
case 3:a++; b++;
}
printf(“a=%d,b=%d”,a,b); }
运行结果为: 。
3.2.3 实验题目
1. 有一函数:
x (x<1) y= 2x-1 (1≤x≤10) 3x-11 (x≥10)
用scanf函数输入x的值,求y值。运行程序,输入x的值(分别为x<1、1≤x<10、x≥10三种情况),检查输出的y值是否正确。
2. 编写程序,输入一位学生的生日(年:y0、月:m0、日:d0),并输入当前的日期(年:y1、月:m1、日:d1)。
输出该学生的实际年龄。
3. 编写程序,输入一个整数,打印出它是奇数还是偶数。
4. 计算器程序。用户输入两个运算数和四则运算符,输出计算结果。
5. 给一个不多于5位的正整数,要求:①求出它是几位数;②分别打印出每一位数字;③按逆序打印出各位数
字,例如原数是321,应输出123。
6. 据有关生理卫生知识与数理统计分析表明,影响小孩成人后身高的因素有遗传、饮食习惯与坚持体育锻炼等。
小孩成人后身高与其父母身高和自身性别密切相关。设faHeight为其父身高,moHeight为其母身高,身高预测公式为:男性成人时身高 = (faHeight + moHeight) * 0.54(cm) 女性成人时身高 = (faHeight * 0.923 + moHeight) / 2(cm)
此外,如果喜爱体育锻炼,那么可增加身高2%,如果有良好的卫生饮食习惯,那么可增加身高1.5%。 编程从键盘输入你的性别(用字符型变量sex存储,输入字符F表示女性,输入字符M表示男性)、父母身高(用实型变量存储,faHeight为其父身高,moHeight为其母身高)、是否喜爱体育锻炼(用字符型变量sports存储,输入字符Y表示喜爱,输入字符N表示不喜爱)、是否有良好的饮食习惯等条件(用字符型变量diet存储,输入字符Y表示喜爱,输入字符N表示不喜爱),利用给定公式和身高预测方法对你的身高进行预测。
15
实验四 循环结构程序设计
4.1 实验目的与要求
1. 熟练掌握while、do-while语句实现循环的方法。 2. 熟练掌握for语句实现循环的方法。 3. 熟练应用循环嵌套结构结局解决问题。
4.2 实验内容
4.2.1 典型例题分析
【例4.1】编程实现,一个10万以内的整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
分析:我们假设,符合条件的数为i,i加上100后是x的完全平方数,i加上100再加上168又是y的完全平方数。即如果i满足条件x*x==i+100&&y*y==i+268,i即是结果。
由题目知:i是一个10万以内的整数,我们可以用循环语句for(i=1;i<100000;i++)来判断100000以内的每一个数是否满足条件。
程序源代码: #include\"math.h\" main() {
long int i,x,y,z; for(i=1;i<100000;i++) {
x=sqrt(i+100); /*x为加上100后开方后的结果*/
y=sqrt(i+268); /*y为再加上168后开方后的结果*/
if(x*x==i+100&&y*y==i+268)/*如果一个数的平方根的平方等于该数,这说明此数是完全平方数*/ printf(\"%ld\\
} }
程序运行结果:
21 261 1581
4.2.2 程序调试
一、 VC的调试功能
对于比较复杂的程序,有些算法结构类错误或其它隐含错误不容易被发现和改正,这时我们可以利用VC的调试功能。
1. 使程序执行到需要的那一行暂停,其中一种方法是: (1) 定位光标,在需要暂停的行上单击鼠标。 (2) 单击菜单“编译”→“开始调试”→“Run to Cursor”,(或按【Ctrl】+【F10】键)程序执行到光标所在行将会暂停。如果需要程序从当前的暂停点继续执行到新的光标位置,可以把光标移动到后面的某个位置,再按【Ctrl】+【F10】键。
另一种方法是设置断点 (1) 在需设置断点的行上单击鼠标,定位光标;按“编译微型条”(图4-1)中最右面的按钮,如下图所示(或
16
按【F9】键)。被设置了断点的行前面会有一个红色圆点标志。(图4-2)
图4-1 编译微型条
断点标志
图4-2 设置了断点
(2) 按【F5】键, 执行到设置断点的行。
注意:设置的断点位置一定要是程序执行的必经之路,如果设置在可能不会执行的语句(比如可能不会执行的分支结构中的语句),这时程序将一直执行到结束或下一个断点为止。
使程序执行到指定位置时暂停有什么作用呢?它可以让我们更方便观察一些变量的值在程序执行过程中的变化情况(这样就需要设置需观察的结果变量),就比较容易找到程序中的错误(Bug)。 2. 设置需观察的结果变量
可以在右下角Watch窗口的“Name”框中填入相应变量名。(图4-3)(当我们设置了断点,执行到断点暂挺后,Watch窗口会自动出现在窗口下面)
图4-3 Watch窗口中的“Name”框
17
3. 单步执行
如果怀疑一小段程序可能有错,可以在该段程序的第一行设置断点,按【F5】键, 执行到该设置断点的行,这时窗口下面会出现“Name”框,在“Name”框中输入需要观察值的变化情况的变量,然后单步执行,即一次执行一行语句,(单步执行按“调试工具栏”(图4-4)中“Step Over”按钮或【F10】键),这样逐行执行比较容易发现错误。
图4-4 调试工具栏
4. 结束调试
按【Shift】+【F5】或菜单Debug → Stop Debugging可以结束调试程序。
表4-1 常用的调试命令
功能 运行到当前光标处 单步执行但不进入调用函数 进入函数单步执行 运行程序至断点,或程序结束 “可以结束调试 跳出当前函数,回到调用处 设置断点
快捷键 【Ctrl】+【F10】 【F10】 【F11】 【F5】 【Shift】+【F5】 【Shift】+【F11】 【F9】 菜单项 Run to Cursor Step Over Step Into Go Stop Debugging Step Out 二、 调试过程
以下面的程序为例介绍具体的调试过程。 【例4.2】题目:打印出所有的“水仙花数”,所谓“水仙花数”是指一个三位数,其各位数字立方和等于该数本身。例如:153是一个“水仙花数”,因为153等于1的三次方加5的三次方加3的三次方。
程序分析:利用for循环控制100-999个数,每个数分解出个位,十位,百位。用变量k, j, i分别表示一个三位数n的个位,十位,百位
程序源代码:
#include\"stdio.h\" main() {
int i,j,k,n; /* k, j, i分别表示n的个位,十位,百位*/ printf(\"'water flower'number is:\"); for(n=100;n<1000;n++) {
i=n%100;/*分解出百位*/ j=n/10%10;/*分解出十位*/ k=n/10;/*分解出个位*/
if(i*100+j*10+k==i*i*i+j*j*j+k*k*k) {
printf(\"%-5d\
18
} }
printf(\"\\n\");
}
程序运行结果如图4-5,该程序的运行结果显然不正确。我们通过调试程序来找出问题。
图4-5 例4.2的运行结果
(1) 在该源程序的关键行插入一个断点。在该行出现了一个断点标识――红色实心圆。(见图4-6)
图4-6 插入断点
(2) 按F5键运行程序到断点处,进入调试模式。
将需要观测的变量输入到屏幕右下方的“Watch”窗口中,这里我们对变量n 、i、j、k的值进行监测,看对于一个给定的n ,i、j、k的值是否我们所期望的结果。(k, j, i分别表示n的个位,十位,百位)由图4-7中各变量的值可知i、k显然不是表示n的百位和个位,由此可见计算i、k的表达式有错误,程序中计算i、k的值的语句应该分别改为: i=n/100; k=n%10; I. 修改错误后,结束调试(按【Shift】+【F5】),光标定位在设置断点的一行,按【F9】取消断点。 II. 运行程序(【Ctrl】+【F5】),得到正确的结果。
19
图4-7 Watch窗口中对变量值的监控
三、 上机调试练习
1. 分析并运行以下程序
#include\"stdio.h\" main( ) {
int i,sum; i=1; sum=0;
while(i<=100) {
sum=sum+i; i++; }
printf(\"sum=%d\\n\}
运行结果为: 。
(1) 如果要求1到1000的和,本程序应该怎么改?
(2) 改进程序,可以求m+(m+1)+„„+n的和(m,n为任意整数)。 2. 将下面的程序修改为求8!。
#include”stdio.h”
20
main( )
{ int i,sum; i=1; sum=1;
while(i<=6) {
sum=sum*i; i++; }
printf(\"sum=%d\\n\
}
3. 分析并运行以下程序
#include”stdio.h” main( ) {
int i,sum; sum=0;
for(i=1;i<=100;i++) {
if(i==4)break;
sum=sum+i; }
printf(\"sum=%d\\n\}
运行结果为: 。
大家将本题中的break改为 continue看看结果有什么不一样,分析原因。 4. 分析并运行以下程序
# include int f,f1,f2,i; f1=0; f2=1; printf(\"%d %d\ for(i=3;i<=5;i++) { f=f1+f2; printf(\"%d\ f1=f2; f2=f; } printf(\"\\n\"); } 运行结果为: 。 5. 分析并运行以下程序 #include”stdio.h” main( ) { int k=5,n=0; while(k>0) 21 { switch(k) { default:break; case 1: n+=k; case 2: case 3:n+=k; } k--; } printf(\"%d\\n\} 运行结果为: 。 4.2.3 实验题目 1. 2. 3. 4. 编写程序,求1-3+5-7+„-99+101的值。 编写程序,求1!+3!+5!+7!+9! 有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和。 一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高? 5. 一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。 6. 求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加), 7. 编写程序,输出从公元1000年至2000年所有闰年的年号。每输出3个年号换一行。判断公元年是否为闰年 的条件是: (1) 公元年数能被4整除,而不能被100整除。 (2) 公元年数能被400整除也是闰年。 22 实验五 综合性实验(一) 5.1 实验目的与要求 1. 能综合运用选择语句、循环语句和跳转语句解决较复杂的问题。 2. 掌握一些常用的算法,如穷举法、迭代法。 3. 掌握循环的嵌套应用。 5.2 实验内容 5.2.1 典型例题分析 【例:5.1】编程实现,将一个大于1的正整数分解质因数。例如:输入90,打印出90=2*3*3*5。 程序分析:对n进行分解质因数,应先找到一个最小的质数i,然后按下述步骤完成: (1) 如果这个质数恰等于n,则说明分解质因数的过程已经结束,打印出即可。 (2) 如果n不等于i,但n能被i整除,则应打印出i的值,并用n除以i的商,作为新的正整数n,重复执行第一步。这一步的作用是找出n中的所有相同质因子i。例如4=2*2 。 (3) 如果n不能被i整除,说明i不是n的质因子, 则用i+1作为i的值,重复执行第一步。 流程图见图5-1 程序源代码: #include\"stdio.h\" main() { int n,i; printf(\"\\nplease input a number:\\n\"); scanf(\"%d\printf(\"%d=\for(i=2;i<=n;i++) { while(n!=i) { if(n%i==0) { printf(\"%d*\n=n/i; } else break; } } printf(\"%d\} 23 开始 输入n的值 2→i N n等于i Y N n%i等于0 Y i++ 输出i的值 n=n/i 输出i的值 结束 图5-1 流程图描述 5.2.2 程序调试 1. 分析并运行以下程序 #include”stdio.h” main( ) { int k,i,j; for(i=0;i<=2;i++) { for(k=1;k<=i;k++) printf(\" \"); for(j=0;j<=3;j++) printf(\"*\"); printf(\"\\n\"); 24 } } 运行结果为: 。 2. 分析并运行以下程序 #include”stdio.h” main( ) { int i,s; s=0; for(i=1;i<=10;i++) { s=s+i; if(s>5)break; printf(\"s=%d\\n\ } } 运行结果为: 。 3. 分析并运行以下程序 #include”stdio.h” main( ) { int a=1,b; for(b=1;b<=10;b++) { if(a>=8) break; if(a%2==1) { a+=5; continue; } a=3; } printf(\"%d\\n\} 运行结果为: 。 4. 分析并运行以下程序 #include\"stdio.h\" main ( ) { int x=9; for (; x>0; x--) { if (x%3==0) { printf(“%d”,--x); continue ; } } } 运行结果为: 。 25 5. 分析并运行以下程序 #include\"stdio.h\" main ( ) { int k=0,m=0,i,j; for (i=0; i<2; i++) { for (j=0; j<3; j++) k++ ; k-=j ; } m = i+j ; printf(“k=%d,m=%d”,k,m) ; } 运行结果为: 。 6. 分析并运行以下程序 #include\"stdio.h\" main ( ) { int a,b; for (a=1,b=1;a<=100;a++) { if (b>=20) break; if (b%3==1){b+=3;continue;} b-=5; } printf(“%d\\n”,a); } 运行结果为: 。 5.2.3 实验题目 1. 编写一个程序,输出1~1000之内所有的非素数(注意:素数即质数)。 2. 将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。 3. 有3个红球、5个白球和6个黑球,从中任意取出8个球,且其中必须有白球。请编程实现输出所有可能方 案。 4. 两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向 队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。 5. 在歌星大奖赛中,有10个评委为参赛的选手打分,分数为1到100分。选手最后得分为:去掉一个最高分 和一个最低分后其余8个分数的平均值。请编写一个程序实现。 26 实验六 函数 6.1 实验目的与要求 1. 掌握函数的定义和调用的方法。 2. 理解和掌握多模块的程序设计与调试的方法。 3. 掌握函数的嵌套调用和递归调用的方法。 4. 掌握全局变量和局部变量,动态变量、静态变量的概念和使用方法。 6.2 实验内容 6.2.1 典型例题分析 【例6.1】用函数编程实现,求20以内的所有素数,按每行显示四个素数输出。 分析:设判断素数的函数名为prime。因为是用来判断一个整数是否素数,所以该函数应该有一个整型参数。判断是否素数有“是”和“否”两种情况,完成判断的函数的返回值通常是0或1,作为逻辑值使用。用1表示“是”素数,用0表示“不是”素数。所以prime函数应该有返回值。 判断素数的算法: 要证明i是素数,只要证明2到i的平方根之间的数都无法被i整除。 (1) 用变量flag来标识i是否有因子,先假设i为素数,故flag初始值为1,如果有因子flag的值就变为0,否则flag的值就为1。 (2) 把flag作为prime函数的返回值。 源程序代码 #include #define N 20 //定义符号常量N值为20 main() { int a,i,j,m=0; for(i=2;i<=N;i++) // 依次判断2到20之间的数是否是素数 { if (prime( i)) { printf(\"%3d\ m++; // m记录找到的素数的个数,因下一语句要根据m的值每输出4个素数换行 if(m%4==0) //实现每输出4个素数换行 printf(\"\\n\"); } } } int prime(int a) //判断是否素数的函数 { int i,k; int flag=1; //flag为0标记a不是素数,为1是素数;此处先假设a为素数,故初始为1 k=sqrt(a); for(i=2;i<=k;i++) 27 if (a%i==0) { flag=0; break;/*找到2与k之间有个数能被i整除,说明a不是素数,将flag置为 0,并退出循环 */ } // 若在上面的循环中flag未被置为0,则说明a为素数 return flag; } 6.2.2 程序调试 1. 分析并运行下列程序。 #include”stdio.h” void swap(int x,int y) { int t; t=x;x=y;y=t; printf(\"%d %d \} main( ) { int a=3,b=4; swap(a,b); printf(\"%d%d\\n\} 2. 分析并运行下列程序。 func(int a,int b) { static int m=0,i=2; i+=m+1; m=i+a+b; return(m); } #include”stdio.h” main( ) { int k=4,m=1,p1,p2; p1=func(k,m) ; p2=func(k,m) ; printf(“%d,%d\\n”,p1,p2) ; } 3. 分析并运行下列程序。 #include\"stdio.h\" fun(int a) { int b=0; static int c=3; b++;c++; return(a+b+c); } 28 main( ) { int i, a=5; for(i=0;i<3;i++) printf(\"%d%d\printf(\"\\n\"); } 4. 分析并运行下列程序。 #include void hello_world(void) { printf(\"Hello,world!\\n\"); } void three_hellos(void) { int counter; for(counter=1;counter<=3;counter++) hello_world();/*调用此函数*/ } void main(void) { three_hellos();/*调用此函数*/ } 5. 分析并运行下列程序。 #include\"stdio.h\" int m=13; int fun( int x, int y) { int m=3; return( x*y-m); } main( ) { int a=7,b=5; printf(“%d\\n”, fun(a,b)/m); } 6. 分析并运行下列程序。 #include”stdio.h” main( ) { int a=2, i ; for(i=0;i<3;i++) printf(“%4d”,f(a) ) ; } f(int a) { 29 int b=0,c=3; b++; c++; return(a+b+c); } 6.2.3 实验题目 1. 编程实现,求两个正整数的最大公约数和最小公倍数,用一个函数求最大公约数,另一个函数求最小公倍数。 从主函数舒服这两个正整数并输出结果。 2. 编程实现,输出10到99数中能被3整除且至少有一位是4的数。(要求用一个函数来判断一个数是否能被3 整除且至少有一位是4的数) 3. 用递归法求n阶勒让德多项式的值: 1pn(x)x((2n1)xp(x)(n1)p(x))/nn1n2(n0)(n1)(n1) 4. 编程实现,判断一个给定的字符串是否为回文。编写huiwen()函数,使它能检查一个字符串是否是回文,当 字符串是回文时,函数返回字符串:yes!,否则函数返回字符串:no!,并在主函数中输出。所谓回文即 正向与反向的拼写都一样,例如:adgda。 30 实验七 数组 7.1 实验目的与要求 1. 掌握一维数组的定义、数组元素引用的方法 2. 掌握二维数组的定义、数组元素引用的方法 3. 掌握字符数组和字符串函数的使用方法 7.2 实验内容 7.2.1 典型例题分析 1. 从键盘输入10个整数,求最大值、最小值、均值和总和 #include { int a[10],i,max,min,sum=0; float ave; for(i=0;i<=9;i++) scanf(\"%d\ max=a[0]; min=a[0]; for(i=0;i<=9;i++) {sum+=a[i]; if(a[i]>max) max=a[i]; if(a[i] printf(\"%d %d %f %d\\n\} 2. 下面的程序实现的是将2*3的矩阵进行转置。 #include {int a[2][3]={{7,9,3},{6,2,4}}; int b[3][2],i,j; for(i=0;i<2;i++) { for(j=0;j<3;j++) { printf(\"%d \ b[j][i]=a[i][j]; } printf(\"\\n\"); } for (i=0;i<3;i++) { for (j=0;j<2;j++) printf(\"%d \ printf(\"\\n\"); } } 31 3. 从键盘上输入源串和目标串,判断源串是否包含目标串 #include\"stdio.h\" #include\"string.h\" main() { char strsource[50],straim[50]; //定义两个字符型数组 int sign,i,j,point; printf(\"\\ninput the source str:\\n\"); // 输入原串 scanf(\"%s\ printf(\"input the aim str:\\n\"); // 输入待匹配的串 scanf(\"%s\ for(i=0;i<=(strlen(strsource)-strlen(straim));i++) { point=i; sign=1; for(j=0;j if(!sign) // 找不到匹配字符串 printf(\"No find!\\n\"); } 4. 输出两个字符串中相同的字符 #include \"stdio.h\" main( ) { char str1[10],str2[10]; // 存放输入的两个字符串 char str3[10]; // 存放输入的两个字符串的交集 int count1=0,count2=0; // 分别记录两个字符数组的长度 int count3=0; // 交集数组的长度 scanf(\"%s\ scanf(\"%s\ while(str1[count1]!='\\0') // 逐一考查str1中的每一个字符 { count2=0; while(str2[count2]!='\\0') // 在str2中搜索相同的字符 { if(str1[count1]==str2[count2]) // 若找到相同字符 { str3[count3]=str1[count1]; // 将当前字符存入交集数组中 count3++; break; } count2++; } count1++; } str3[count3]='\\0'; if(str3[0]!='\\0') 32 printf(\"%s\\n\ } 7.2.2 程序调试 1. 请将以下程序的执行结果界面复制到实验报告中。 #include void fun(int a, int b) { int t; t=a; a=b; b=t; } main() { int c[10]={1,2,3,4,5,6,7,8,9,0}, i; for (i=0; i<10; i+=2) fun(c[i], c[i+1]); for (i=0; i<10; i++) printf(\"%d,\printf(\"\\n\"); } 2. 请将以下程序的执行结果界面复制到实验报告中。 #include for(i=0;i<=n;i++) r=r*b[i]; return r; } main() { int x,a[]={2,3,4,5,6,7,8,9}; x=f(a,3); printf(\"%d\\n\} 3. 请将以下程序的执行结果界面复制到实验报告中,并指出该程序的功能。 #include int i, j, row, column,m; static int array[3][3]={{100,200,300},{28,72,-30},{-850,2,6}}; m=array[0][0]; for (i=0; i<3; i++) for (j=0; j<3; j++) if (array[i][j] printf(\"%d,%d,%d\\n\} 33 4. 请将以下程序的执行结果界面复制到实验报告中,并指出该程序的功能。 #include { int a[6][6],i,j ; for (i=1; i<6 ; i++) for (j=1 ; j<6 ; j++) a[i][j]=(i/j)*(j/i) ; for (i=1;i<6 ; i++) { for (j=1 ; j<6 ; j++) printf(\"%2d\ printf(\"\\n\"); } } 5. 请将以下程序的执行结果界面复制到实验报告中。 main( ) { int num[4][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}},i,j; for(i=0;i<4;i++) { for(j=0;jprintf(\"%4d\printf(\"\\n\"); } } 6. 在要求输入数据时输入I am a student 的功能。 #include char s[80],c1,c2=''; int i=0,num=0; gets(s); while(s[i]!='\\0') {c1=s[i]; if(i==0)c2=''; else c2=s[i-1]; if(c1!=''&&c2=='') num++; i++; } printf(\"There are %d words.\\n\} 7. 请在实验报告中写出以下程序的运行结果,并指出该程序的功能。 #include void f(char p[ ][10],int n) /*字符串从小到大排序*/ { char t[10]; int i,j; for (i=0;i if(strcmp(p[i], p[j])>0) {strcpy(t, p[i]); strcpy(p[i], p[j]); strcpy(p[j], t); } } main( ) { char p[5][10]={\"abc\f(p, 5); printf(\"%d\\n\} 7.2.3 程序改错 1. 下面的程序实现的是将数组a中的最后一个数移到最前面,其余数依次往后移一个位置。 #include {int i,t,a[10]={0,1,2,3,4,5,6,7,8,9}; t=a[9]; for(i=1;i<10;i++) a[i]=a[i-1]; a[0]=t; for(i=0;i<10;i++) printf(\"%d \ printf(\"\\n\"); } 上机运行程序,查看结果是否正确。若不正确,请在实验报告中写出错误原因,并将修改后的程序和程序执行结果界面复制到实验报告中。 2. 下面的程序实现的是将4*4的矩阵转置 #include {int a[4][4]; int i,j; for(i=0;i<4;i++) for(j=0;j<4;j++) scanf(\"%d\ for(i=0;i<4;i++) for(j=0;j<4;j++) { t=a[i][j]; a[i][j]=a[j][i];a[j][i]=t;} for (i=0;i<4;i++) { for (j=0;j<4;j++) printf(\"%d \ printf(\"\\n\"); } } 上机调试程序并改正程序中的错误。查看结果是否正确。若不正确,请在实验报告中写出错误原因,并将修改后的程序和程序执行结果界面复制到实验报告中。 7.2.4 实验题目 1. 输入十个整数,计算出平均值(aver),找出其中最大者(max)和最小者(min)并将三者输出。 2. 编写函数把数组中所有奇数放在另一个数组中返回。 35 3. 输入10个学生的单科成绩,然后按从高到低排序后输出。 4. 将一整数数列按奇数在前,偶数在后的顺序重新排放,并要求奇偶两部分都是升序排列。 5. 将十个整数输入数组a,逆序存放后再输出数组a。例如:原来顺序为6,8,5,4,1。要求改为1,4,5, 8,6。 6. 求整数m的所有素数因子,并输出。 7. 调用随机函数为5*4的矩阵置100以内的整数,输出该矩阵,求出每行元素之和,并把和值最大的那一行与 第一行上的元素对调。若已定义x为int类型,调用随机函数步骤如下: #include \"stdlib.h\" . . x=rand()%100 /*产生0到100的随机数*/ 8. 调用随机函数为5*5的矩阵置100以内的整数,输出该矩阵,然后逆置该矩阵。即将第一列的元素放在第一 行上、第二列的元素放在第二行上、其它依次类推。 9. 编写函数把任意十进制下整数转换成二进制数。提示:把十进制数不断被2除余数放在一个一维数组中,直 到商数为零。在主函数中进行输出,要求不得按逆序输出。 10. 编写程序求两个矩阵的和。 11. 对三人的四门课程分别按人和科目求平均成绩,并输出包括平均成绩的二维成绩表。 12. 编写程序打印出以下形式的乘法九九表。 ** A MULTIPCATION TABLE ** (1) (2) (3) (4) (5) (6) (7) (8) (9) (1) 1 2 3 4 5 6 7 8 9 (2) 2 4 6 8 10 12 14 16 18 (3) 3 6 9 12 15 18 21 24 27 (4) 4 8 12 16 20 24 28 32 36 (5) 5 10 15 20 25 30 35 40 45 (6) 6 12 18 24 30 36 42 48 54 (7) 7 14 21 28 35 42 49 56 64 (8) 8 16 24 32 40 48 56 64 72 (9) 9 18 27 36 45 54 63 72 81 13. 输入一行字符,统计其中的数字、字母、空格和其它字符出现的次数。 14. 编写程序: (1) 求一个字符串S1的长度; (2) 将一个字符串S1的内容复制给另一个字符串S2; (3) 将两个字符串S1和S2连接起来,结果保存在S1字符串中; (4) 搜索一个字符在字符串中的位置(例如:'I'在\"CHINA\"中的位置为3) 。如果没有搜索到,则位置为-1。 (5) 比较两个字符串S1和S2,如果S1>S2,输出一个正数;如果S1=S2,输出0;如果S1 m的值并输出复制结果,在被调用函数中完成复制。 17. 有一篇文章,共有3行文字,每行有80个字符。要求分别统计出其中英文大写字母,小写字母,中文字母, 中文字符,数字,空格及其他字符的个数。(提示:中文字符是两个字节,且数值均大于128的字符) 。 36 实验八 综合性实验(二) 8.1 实验目的与要求 1. 能综合运用函数、数组解决较复杂的问题。 2. 掌握利用数组实现一些常用算法(如排序、查找、插入等)的基本技巧。 3. 掌握模块化程序设计方法。 8.2 实验内容 8.2.1 典型例题分析 1. 分析下面的程序并上机运行,将执行结果界面复制到实验报告中,并指出该程序的功能。 #include void sort(int a[ ],int n) { int i,j,t; for(i=0;i { int aa[10]={1,2,3,14,5,6,71,8,19,10},i; sort(aa+2,5); for(i=0;i<10;i++) printf(\"%d,\printf(\"\\n\"); } 如果想对数组aa中的10个数进行从大到小排序,语句sort(aa+2,5);应该如何修改? 8.2.2 程序调试 1. 请将以下程序的执行结果界面复制到实验报告中。 #include main( ) { int a[10]={1,2,3,4,5,6,7,8,9,10}; sum(&a[2]); printf(\"%d\\n\} 2. 请将以下程序的执行结果界面复制到实验报告中。 #include void fun(int a[ ],int n,int m) { int i; 37 for(i=m;i>n;i--) a[i+1]=a[i]; } main( ) { int i,a[N]={1,2,3,4,5,6,7,8,9,10}; fun(a,2,9); for(i=0;i<5;i++) printf(\"%d\} 8.2.3实验题目 1. 编写一个程序,完成以下功能: (1) 输入10个学生的单科成绩(0-100之间) (2) 从小到大排序 (3) 输入一个成绩x(0-100之间) ,在已经排序的学生成绩中进行查找。若存在,在主函数中输出其所处的 位置,否则,将x插入适当的位置,新形成的数列仍然按照从小到大排序 要求:函数input实现数据输入,函数sort实现排序,函数search实现查找,函数insert实现插入,函数display实现数据输出。 2. 编写函数对字符数组中的输入字母,按由大到小的字母顺序进行排序。 3. 设某班有3门课程(语文、数学、英语) 的成绩。先输入学生人数,然后按学号(设为3位) 从小到大的顺序 依次输入学生学号和学生成绩。编写一个程序实现: (1) 统计每门课程全班的总成绩和平均成绩 (2) 统计每个学生的总成绩和平均成绩 (3) 按总分从高到低顺序输出学生的学号、各门课程成绩及总成绩。 38 实验九 指针 9.1 实验目的与要求 1. 2. 3. 4. 5. 6. 理解指针的概念,正确定义和使用指针变量。 通过实验进一步掌握指针的概念,会定义和使用指针变量。 能正确使用数组的指针和指向数组的指针变量。 能正确使用字符串的指针和指向字符串的指针变量。 能正确使用指向函数的指针变量。 了解指向指针的指针的概念及其使用方法。 9.2 实验内容 9.2.1 典型例题分析 1. 下面的程序实现的是利用指针交换两个整数 #include { int m,n,*pm,*pn,temp; // 定义整型变量和指向整型数据的指针变量 pm=&m; // 指针pm指向变量m pn=&n; // 指针pn指向变量n scanf(\"%d%d\利用指针输入整型数据m和n temp=*pm; // 利用指针进行数据交换,设中间变量temp *pm=*pn; *pn=temp; printf(\"%d,%d\\n\// 输出m和n的结果 printf(\"%d,%d\\n\ // 利用指针输出结果 } 2. 下面的程序实现的是:输入三个整数,按由小到大的顺序输出。 #include void swap(int *p1,int *p2) { int p; p=*p1; *p1=*p2; *p2=p; } main() { int n1,n2,n3,*p1,*p2,*p3; scanf(\"%d%d%d\// 利用指针输入整型数据n1,n2和n3 p1=&n1; // 指针p1指向变量n1 p2=&n2; // 指针p2指向变量n2 p3=&n3; // 指针p3指向变量n3 if(n1>n2) swap(p1,p2); if(n1>n3) swap(p1,p3); if(n2>n3) swap(p2,p3); 39 printf(\"%d %d %d\\n\// 利用指针输出结果 } 3. 下面的程序实现的是将一个字符串中所有字符复制到另一个数组中 #include {char a[]=\"I am a student\int i,j; for (i=0;*(a+i)!='\\0';i++) *(b+i)=*(a+i); // 逐个字符复制,达到字符串复制效果 *(b+i)='\\0'; //加截至符 printf(\"String a is:%s\\n\ //输出字符串a printf(\"String b is:\"); //通过循环逐个字符输出,达到输出效果 for (i=0;b[i]!='\\0';i++) printf(\"%c\} 4. 下面的程序实现的是输入三个字符串,再逐个输出。