描述
开 本: 16开纸 张: 胶版纸包 装: 平装-胶订是否套装: 否国际标准书号ISBN: 9787302500827丛书名: 21世纪高等学校计算机教育实用规划教材
全书共分为4部分,内容包括:C程序运行环境(Microsoft Visual C 6.0和C-Free 5.0)、C程序设计上机实验项目(17个)、C程序典型题解(40个)及C语言程序设计选择题集(525个)等。本书内容丰富,实用性强,具有启发性,是学习C语言的参考必备用书。
第1章 Visual
C 6.0实验环境… 1
1.1
VC 6.0概述… 1
1.2
VC 6.0的启动… 1
1.3 建立新工程… 1
1.4 编译并连接程序… 7
1.5 程序的错误修改… 8
1.6 单步调试… 8
1.7 生成可执行文件并发布… 10
第2章 C-Free
5.0实验环境… 11
2.1 C-Free
5.0概述… 11
2.2 C-Free
5.0的启动… 11
2.3 建立新工程… 11
2.4 编译并运行程序… 14
2.5 程序的错误修改… 15
2.6 程序调试… 15
2.7 生成可执行文件并发布… 16
第3章 实验项目… 17
实验项目1 运行一个C程序… 17
实验项目2 数据类型与表达式… 19
实验项目3 顺序结构程序设计方法… 26
实验项目4 分支结构程序设计方法… 29
实验项目5 循环结构程序设计方法… 35
实验项目6 分支与循环结构综合程序设计… 42
实验项目7 一维数组程序设计… 47
实验项目8 二维数组程序设计… 50
实验项目9 字符数组程序设计… 55
实验项目10 数组与指针程序设计… 59
实验项目11 函数的定义和调用… 63
实验项目12 函数的嵌套调用与递归函数… 67
实验项目13 变量的作用域与存储属性… 73
实验项目14 指针与函数… 77
实验项目15 结构体应用… 82
实验项目16 文件及应用… 87
实验项目17 C语言程序综合应用… 91
第4章
C程序典型题解… 93
第5章 C语言程序设计选择题集… 157
习题1 数据类型及表达式、关系运算、逻辑运算与条件运算… 157
习题2 选择结构… 167
习题3 循环结构… 176
习题4 数组… 186
习题5 函数和编译预处理… 202
习题6 指针… 224
习题7 结构体… 236
习题8 共用体… 241
习题9 链表… 242
习题10 位运算… 244
习题11 文件… 246
参考文献……………………………………………………………………………………………………… 251
程序设计是一门操作性较强的专业技术,为了在学习理论知识的同时,更进一步增强读者的实践能力,帮助读者深刻理解C语言程序设计中的基本概念及原理,本书主要以实验训练的方式,通过实践对各知识点进行分析、验证以及拓展,加深读者对知识点的理解和掌握程度,提高学习效率。 本书第1版于2015年2月出版发行,自出版以来获得众多师生的认可。在受到肯定的同时,也收到较多读者对本书的使用体会和建议。笔者结合最新教学大纲变化,总结前期师生给予的教学反馈,对本书第1版进行了修订,推出第2版。更新后的版本中,根据教学大纲及读者反馈,已对相应的内容作了更新和补充说明,前期版本中出现的个别文字或符号错误也已进行了修正,对个别章节的内容还作了适当调整。在此,向给予帮助的各位同仁表示感谢,也希望大家继续支持第2版,并提出批评和指正建议,激励我们更进一步完善。 本书是与《C语言程序设计案例教程(第2版)》相配套的辅助教学教材,重点突出实践教学环节。全书共4部分内容,依次为C程序运行环境(Microsoft Visual C 6.0和C-Free 5.0)、C程序设计实验项目、C程序典型题解和C语言程序设计选择题集。 其中,第一部分对C语言的开发环境(Microsoft Visual C 6.0和C-Free 5.0)进行较全面的介绍。第二部分提供了学习C语言程序设计需要进行的17个实验项目,每个实验项目均明确实验目的和实验内容。实验内容分为三类:第一类是验证性实验,对每个实验题都进行了详细的分析与描述;第二类是设计性实验,要求读者在掌握验证性实验的基础上能自行设计程序来解决一些实际问题;第三类是提高性实验,为学有余力的读者提供自我挑战的机会。第三部分是在学习课程知识的基础上搜集到的C程序典型问题,以图丰富学生的实战经验。最后为C语言程序设计选择题集,它覆盖了C语言的主要知识点,进一步为读者掌握C语言提供帮助。 本书作者均为多年从事C语言程序设计教学、具有丰富教学经验的高校教师。整体内容的顺利完成都是他们对多年教学经验的总结和共同努力的结果,在此向他们致以崇高的敬意,也更希望本书能对广大读者有所帮助。 本书内容设计合理,解答详尽,通俗易懂,有利于读者参考和自学。书中涉及的所有代码均在Microsoft Visual C 6.0集成开发环境下编译通过。 本书由刘小军主编,参加编写的人员还有张丽华、张彬、宋柱芹、殷联甫、梁田5位老师。 由于编者水平有限,不足或遗漏之处在所难免,敬请广大读者及同仁批评指正。 编 者 2018年1月
图3-1 从键盘输入两个整数并求它们的和 ① 去掉“#include ”,运行程序,观察运行结果,并分析为什么。 ② 去掉“int a,b,c;”语句后的“;”,运行程序,观察运行结果,并分析为什么。 ③ 将“c=a b;”改为“C=a b;”,运行程序,观察运行结果,并分析为什么。 (2)尝试改正下列程序中的错误,直到程序经编译后没有错误信息,并得到题目要求的运行结果。 题目要求得到的输出结果如图3-2所示。
图3-2 题目要求得到的输出结果 含有错误的源程序如下: #includeint main(){ int a=1;b=2,c=3, printf(“output:%d,%d,%dn”a,b,c); return 0;} 2.设计性实验 (1)编写程序,从键盘输入两个整型变量a和b,求它们的差并输出,图3-3所示是一个示例结果。
图3-3 从键盘输入两个整数并求它们的差 (2)编写程序,从键盘输入x的值,根据公式y=x2 1求y的值,输出x和y的值(假设x和y都是int型变量),图3-4所示是一个示例结果。
图3-4 求x2 1的值 实验提示: x2可表示为x*x。 (3)编写程序,从键盘输入x的值,求x的平方根并赋给变量y,输出x和y的值(假设x和y都是int型变量),图3-5所示是一个示例结果。
图3-5 求x的平方根 实验提示: 可用函数sqrt(x)求x的平方根,要使用该函数,必须在程序前面加上头文件math.h。实验项目2 数据类型与表达式一、实验目的 (1)掌握C语言基本数据类型的常量表示、变量的定义和使用。 (2)掌握C语言各类运算符的优先级、结合性及相应表达式的求值方法。 (3)掌握不同类型数据之间的赋值规律,理解自动与强制数据类型转换。 (4)学会编写程序求表达式结果的方法。 (5)掌握C语言基本数据类型数据的输入方法。 (6)掌握常见格式控制字符对输出结果的控制作用。 (7)理解数据溢出错误和舍入误差(以整型、实型数据为例)。 (8)掌握指针的简单使用方法。 (9)进一步熟悉C程序的实现过程。二、实验要求 (1)实验时仔细对比程序实际运行结果,认真分析并回答思考中的问题。 (2)如果程序有错,记录编译、连接、运行过程中遇到的提示错误。分析出错原因,记下更正的方法。 (3)可以对实验程序进行修改、补充,以便完成自己需要的程序验证和测试。在完成实验要求的工作外,要学会创造性地工作。三、实验内容 1.验证性实验 (1)输入以下程序,运行后分析结果。 #includeint main(){ int i,j,m,n; i=97;j=65; m= i; n=j ; printf(“i=%d,j=%d,m=%d,n=%dn”,i,j,m,n); printf(“i=%c,j=%c,m=%c,n=%cn”,i,j,m,n); /*printf(“i=%f,j=%f,m=%f,n=%fn”,i,j,m,n);*/ return 0;} 程序运行结果如图3-6所示。
图3-6 程序运行结果 ① 程序中语句“m= i;”起什么作用? ② 程序中语句“n=j ;”起什么作用? ③ 程序中语句“printf(“i=%d, j=%d, m=%d,n=%dn”,i,j,m,n);”起什么作用? ④ 程序中语句“printf(“i=%c, j=%c, m=%c, n=%cn”,i,j,m,n);”起什么作用? ⑤ 程序中语句“/*printf(“i=%f, j=%f, m=%f, n=%fn”,i,j,m,n);*/”执行了吗?如果把其中的/*和*/去掉,变成语句“printf(“i=%f, j=%f, m=%f,n=%fn”,i,j,m,n);”,在VC 6.0中运行会出现图3-7所示的运行结果,这是一个什么错误?为什么会出现这个错误?
图3-7 修改后的运行结果与错误提示 (2)输入以下程序,运行前将程序中的k分别赋值为127、?128、128和?129,分析程序运行结果。 #includeint main(){ float a=3.7,b; int i,j=5; int k=127;/*分别用127,-128,128,-129测试*/ unsigned u; long l; char c; i=a;printf(“%dn”,i); /*实型赋值给整型*/ b=j;printf(“%fn”,b); /*整型赋值给实型*/ u=k;printf(“%d,%un”,u,u); /*相同长度类型之间赋值*/ l=k;printf(“%ldn”,l); /*整型赋值给长整型,短的类型赋值给长的类型*/ c=k;printf(“%dn”,c); /*整型赋值给字符型,长的类型赋值给短的类型*/ return 0;} ① 编译时有没有出现警告提示?连接时有没有出现错误?运行时呢?换一个编译器试试。不同的编译器对数据类型的数据范围检查的严格程度都相同吗?图3-8所示为VC 6.0中的一个运行结果(k=127时)。
图3-8 k=127时的运行结果 ② 修改k的值,再运行程序,分析运行结果。 (a)k=128 (b)k=?128 (c)k=?129 ③ 图3-9所示为VC 6.0中的三个运行结果(k分别为128、?128和?129时)。
(a)k=128 (b)k= ?128 (c)k= ?129图3-9 k分别为128、?128和?129时的运行结果 ④ 修改k的值为127,分别把“i=a;printf(“%dn”,i);”和“b=j;printf(“%fn”,b);”改为“i=a;printf(“%fn”,i);”和“b=j;printf(“%dn”,b);”,再运行程序,分析为什么会出现图3-10中的运行结果。
图3-10 修改程序后的运行结果 (3)输入以下程序,根据程序运行结果(见图3-11)分析每个关系表达式的值。
图3-11 关系表达式的值#includeint main(){ char c=’k’; int i=1,j=2,k=3; float x=3e 5,y=0.85; printf(“%d,%dn”,’a’ 5=k 1); printf(“%d,%dn”,1 printf(“%d,%dn”,i j k==-2*j,k==j==i 5); return 0;} ① 表达式’a’ 5图3-12 逻辑表达式的值#includevoid main(){ char c=’k’; int i=1,j=2,k=3; float x=3e 5,y=0.85; printf(“%d,%dn”,,!x, !x*!y ); printf(“%d,%dn”, x||i&&j-3, i printf(“%d,%dn”, i==5&&c&&(j=8), x y||i j k ); return 0;} ① 表达式!x*!y的求值过程是怎样的? ② 表达式x||i&&j-3和iint main(){ int a, b,*pa=&a,*pb=&b,max; printf(“please input two intergers: a,bn”); scanf(“%d,%d”,pa,pb); max=*pa>*pb?*pa:*pb; printf(“max=%dn”,max);
return 0;}#include int main(){ int a, b,*pmax=0; printf(“please input two intergers: a,bn”); scanf(“%d,%d”,&a,&b); pmax=a>b?&a:&b; printf(“max=%dn”,*pmax); return 0;} 如图3-13所示,运行两个程序,分别输入3,4并按回车键,运行结果都为max=4。
图3-13 输入3,4时的运行结果 实验提示:运行本程序时,输入的两个整数之间用逗号隔开,按回车键表示输入结束。 ① 求两个整数中的较大数,不用指针是不是更简单?尝试写出程序。 ② 在所写的程序上修改,使得任意输入两个实数,可以输出其中的较大数。 ③ 在所写的程序上修改,使得任意输入两个字符,可以输出其中的ASCII码较 大者。 ④ 换成三个比较对象时,应该如何修改这些程序? 2.设计性实验 (1)已知变量a和b为int型,其值分别为3和10;变量x和y 为double型,其值分别为6.8和1.9,计算算术表达式(double)(a b)/2 (int)x%(int)y的值。试编程验证自己的计算结果是否正确。 实验提示: ① 先命名一个变量用来保存最终结果,例如result;再判断结果应该是什么类型,假设是double型;在程序中根据变量的类型和名字对它进行声明,例如“double result;”。 ② 在程序对a、b、x和y四个变量声明的同时可以赋初值,也可以声明之后再赋值。然后用语句“result=(double)(a b)/2 (int)x%(int)y;”将表达式的值赋给变量result。 ③ 最后在屏幕上输出变量result的值,这个值就是表达式的值。输出double型的变量result的值可以用语句“printf(“result=%lf”,result);”或“printf(“result=%f”,result);”。图3-14所示为一个示例结果。
图3-14 (double)(a b)/2 (int)x%(int)y的值 (2)已知:a=8,n=3(a、n为int型),分析依次计算下面表达式时a的值如何变化,试编程上机验证。 ① a =a ② a*=2 3 ③ a%=(n%=2) ④ a=a 3 ⑤ a =a-=a*=a 实验提示: ① 程序对a和n两个变量声明的同时可以赋初值,也可以声明之后再赋值。 ② 把要计算的表达式后面加上分号,变成表达式语句。这5个表达式语句都是复合赋值表达式或赋值表达式。 ③ 在这5个表达式语句的每个表达式语句之后都加上一个printf()函数调用语句,用来输出变量a的值。 图3-15所示为一个示例结果。 (3)编写程序产生一个如图3-16所示的输出结果。 图3-15 (复合)赋值表达式的值 图3-16 结果样式 实验提示:分析这个输出结果共几行,每行都可以调用printf()函数来实现。 3.提高实验 现在是24小时制的9时30分,编程求出再过1000分钟是24小时制的几时几分?程序结果示例如图3-17所示。
图3-17 程序结果示例 实验提示: 假设今天是周二,则100天后是((100 2)%7)。实验项目3 顺序结构程序设计方法一、实验目的 (1)掌握C语言中使用最多的一种语句——赋值语句的使用方法。 (2)掌握C程序的基本构成,熟悉顺序结构程序设计的一般步骤。二、实验要求 (1)理解C语言中程序设计的基本思路。 (2)能够编写简单的顺序结构程序。三、实验内容 1.验证性实验 (1)对于温度的计算很多国家采用的是华氏温度标准(F),而国内采用的是摄氏温度(C)。现在,请根据温度转换公式设计一个温度转换程序,可以进行温度转换。如果输入摄氏温度,显示转换的华氏温度。运行结果如图3-18所示。
图3-18 温度转换运行结果 温度转换的公式为:F=(C×9/5)+32 实验提示: ① 声明变量f和c。 ② 输入c的值。 ③ 利用公式计算f的值。 ④ 输出f的值。 程序代码参考: #include “stdio.h”int main(){ float f,c; printf(“请输入摄氏温度的值:”); scanf(“%f”,&c); f=c*9/5 32; printf(“华氏温度F=%fn”,f); return 0;} 采用指针实现的程序代码参考: #include “stdio.h”int main(){ float f,c; float *pf=&f,*pc=&c; printf(“请输入摄氏温度的值:”); scanf(“%f”,pc); *pf=*pc*9/5 32; printf(“华氏温度F=%fn”,*pf); return 0;} 如果将语句“f=c*9/5 32;”换成“f=9/5*c 32;”输出结果会是多少呢? (2)从键盘输入任意两个数,输出它们的和值与差值之积,运行结果如图3-19所示。
图3-19 求两数的和值与差值之积的运行结果 实验提示: ① 定义三个变量a,b,s。 ② 输入a,b的值。 ③ 计算它们的和值与差值之积,存放在变量s中。 ④ 输出s的值。 程序参考代码如下: #include “stdio.h”int main(){ int a,b,s; printf(“请输入a,b的值:”); scanf(“%d,%d”,&a,&b); s=(a b)*(a-b); printf(“s=%dn”,s); return 0;} 用指针实现的代码如下: #include “stdio.h”int main(){ int a,b,s; int *pa=&a,*pb=&b,*ps=&s; printf(“请输入a,b的值:”); scanf(“%d,%d”,pa,pb); *ps=(*pa *pb)*(*pa-*pb); printf(“s=%dn”,*ps); return 0;} 能否增加两个变量分别记录两数之和与之差?如果行,将程序改写,并说出哪种写法好及原因。 2.设计性实验 (1)编写程序,输入一个小写字母,改用大写字母输出。 实验提示: ① 声明两个字符型变量,一个存放小写字母,一个存放大写字母。 ② 输入小写字母。 ③ 将小写字母转换成大写字母。 ④ 输出大写字母。 其中第③步关于大小写字母转换的问题,可以利用字符的ASCII码,大写字母A的ASCII码值为65,小写字母a的ASCII码值为97,也就是说,大小写字母的ASCII码的差值为32,运行结果如图3-20所示。
图3-20 小写字母转成大写字母的运行结果 (2)编写程序,输入两个整数分别赋给变量a和b,然后交换两个变量的值再输出。 实验提示: ① 声明两个整型变量a和b。 ② 输入它们的值。 ③ 交换两个变量的值,也就是让a获得b的值,b获得a的值。 ④ 输出变量a和b。 其中第③步交换两个变量值的问题怎么解决呢?就像有两杯水,现在要把两个杯子中的水交换,那么大家很自然想到利用第三个杯子做中介。同样的道理,要交换两个变量的值,我们也需要另外一个变量作为中介。所以在第①步我们需要声明三个变量,运行结果如图3-21所示。 3.提高实验 (1)编写程序,输入存款金额、存款年限和存期的年利率,然后输出到期后的金额。到期金额=存款金额*(1 存期的年利率)存款年限,运行结果如图3-22所示。 图3-21 交换两个变量的运行结果 图3-22 存款到期金额的运行结果 实验提示: ① 声明存款金额、存款年限、存期的年利率、到期后的金额4个变量。 ② 输入需要的值。 ③ 利用公式计算,其中求次方需要用到库函数pow(x,n)。 ④ 输出到期金额。 (2)编写程序,输入长方形的两边长,求它的周长和面积,运行结果如图3-23所示。
图3-23 求长方形的周长和面积的运行结果 实验提示: ① 声明变量。 ② 输入需要的值。 ③ 利用公式计算周长和面积。 ④ 输出周长和面积。实验项目4 分支结构程序设计方法一、实验目的 (1)掌握C程序中if语句的格式及使用方法。 (2)掌握switch语句的格式和使用方法。 (3)学会使用分支结构编写简单的C语言程序。 (4)理解分支结构嵌套的格式和使用方法。二、实验要求 (1)掌握if和switch语句的不同书写格式。 (2)熟悉利用if和switch语句编写简单的分支程序。 (3)明确分支条件的书写方法。三、实验内容 1.验证性实验 (1)输入整数a、b,若a2 b2大于100,则输出a2 b2百位以上的数字,否则输出两数之和,运行结果如图3-24所示。
图3-24 根据a2 b2是否大于100输出不同值的运行结果 实验提示: 分支选择处理的条件是a2 b2>100。如果大于100,就取a2 b2百位以上的数字,如果小于等于100,就输出a b的值。其中求百位以上的数字,可以根据两个整数相除仍然为整数的原则,使用(a2 b2)/100。 ① 首先定义三个整型变量a,b,y,其中y存储需要输出的值。 ② 使用if…else两分支结构编写代码,其中分支条件为a2 b2>100。 ③ 输出y的值。 程序参考代码如下: #includeint main(){ int a, b, y; printf(“enter a, b:”); scanf(“%d, %d”,&a, &b); if((a*a b*b)>100) /*第6行*/ y=(a*a b*b)/100; /*第7行*/ else y=a b; /*第9行*/ printf(“y=%dn”,y); return 0;} ① 程序中第7行语句起什么作用?是否可以使用y=(a^a b^b)/100代替? ② 能够使用if的单分支语句实现上面的程序吗?例如:第6行至第9行使用下面的语句代替。 y=a b; if((a*a b*b)>100) y=(a*a b*b)/100; ③ 分支结构可以用什么运算符实现?请改写这个程序。 (2)从键盘输入3个浮点数a、b、c的值,按从小到大的顺序依次输出,输出时要求保留小数点后两位,运行结果如图3-25所示。
图3-25 三个数按顺序输出的运行结果 实验提示: ① 定义三个double型变量,并从键盘输入。 ② 首次比较a和b的大小,如果a大于b则将a和b的值交换,使得a小于b。 ③ 类似地比较a和c的大小,如果a大于c则将a和c的值交换,使得a小于c,这样a为最小的数。 ④ 再比较b和c的大小,如果b大于c则将b和c的值交换,这样c最大。 ⑤ 最后输出a、b、c的值。 程序参考代码如下: #includeint main(){ double a, b, c, t; printf(“输入a, b, c:”); scanf(“%lf, %lf, %lf”, &a, &b, &c); if(a>b){t=a; a=b; b=t;} /*第6行*/ if(a>c){t=a; a=c; c=t;} if(b>c){t=b; b=c; c=t;} /*第8行*/ printf(“%0.2lf, %0.2lf, %0.2lfn”, a, b, c); /*第9行*/ return 0;} ① 程序第6行语句起什么作用? ② 第6行至第8行的程序段实现了什么功能?举例说明其实现步骤。 ③ 第9行的输出为什么要使用%0.2lf的输出格式? (3)分析题。 实验提示: ① 分析下面的程序,得出输出结果。 ② 输入程序,运行验证。 ③ 画出流程图。 #includeint main(){ int s=0,k; scanf(“k=%dn”,k); switch(k){ case 1: case 4: case 7: s ; break; case 2: case 3: case 6: break; case 0: case 5: s =2; break; } printf(“s=%dn”,s); return 0;} break语句加与不加对程序的输出结果有何影响? 2.设计性实验 (1)有下面的方程式,输入x的值,输出y的值。 x 1 x2 y = x2 ?2?x?2 x>2 实验提示: ① 定义变量x,y。 ② 输入x的值。 ③ 根据x的值,进入相应的分支做运算。 ④ 输出y的值。 程序运行结果如图3-26所示。
图3-26 数学方程式的运行结果 (2)编写一个程序,根据用户输入的三角形的三边a,b,c的长度判定能否构成三角形,如果能构成就输出三角形的面积area,如果不能构成就输出“不能构成三角形!”。 实验提示: ① 确定组成三角形的条件为:任意两边之和大于第三边。 ② 三角形面积的计算公式为:area=,其中,a、b、c为三角形的三边长,s=(a b c)/2。 运行结果如图3-27所示。 (3)已知银行整存整取存款不同期限的月息利率分别为:月息利率=0.33%期限为1年,0.36%期限为2年,0.39% 期限为3年,0.45% 期限为5年,0.54%期限为8年。输入存款的本金和年限,请使用switch语句编程实现求到期时能从银行得到的利息与本金的 合计。 利息的计算公式为:利息=本金×月息利率×12×存款年限,运行结果如图3-28所示。 图3-27 三角形面积的运行结果 图3-28 银行存款的运行结果 实验提示: ① 输出结果是利息与本金之和,那么只要求出利息值就行了。 ② 从利息计算公式中可以看出,存款年限和月利息率是息息相关的,其中存款年限为整数,很自然地就想到利用年限值得到相应的case分支语句。 ③ 假设存款年限用变量year表示,那么就可以得到下面的结构: switch(year){ case 1: case 2: case 3: case 5: case 8: default:} (4)输入一个小写字母,将其转换成大写字母,再输出该字母的前序字母、该字母、该字母的后序字母,例如:输入g,则输出FGH;输入a,则输出ZAB;输入M,则输出LMN;输入Z,则输出YZA。下面给出了程序的部分代码,请把它补充完整,运行结果如图3-29所示。
图3-29 字母转换的运行结果 实验提示: ① 输入字母。 ② 判断输入的字母是否为小写字母。 ③ 如果是小写字母,将其转换为大写字母;对于首位两个字母A和Z需要单独处理。 ④ 输出。 #includeint main(){ char ch,c1,c2; printf(“Enter a character:”); ch=getchar(); /*—请填上适当的语句——*/ {ch-=32; c1=ch-1; c2=ch 1; /*—请填上适当的语句——*/ c1=ch 25; /*—请填上适当的语句——*/ c2=ch-25; putchar(c1); putchar(ch); putchar(c2);} else printf(“您输入的不是小写字母!”); putchar(‘n’); return 0;} 3.提高实验 (1)编写一个程序实现如下功能:输入一个正整数,判断它能否被3,5,7整除,并输出以下信息之一: ① 能同时被3,5,7整除; ② 能被其中两数(要指出哪两个)整除; ③ 能被其中一个数(要指出哪一个)整除; ④ 不能被3,5,7任一个整除。 运行结果示例如图3-30所示。
(a) (b) (c)图3-30 判断能否整除的运行结果示例 实验提示: ① 利用取余运算可以判断一个数能否被另一个数整除。 ② 此题就是要判断输入的数对3、5、7取余,余数是否同时为0。 (2)编写程序输入月份和日期,给出对应的星座。下面是星座计算方法:3月21日~4月20日为白羊座,4月21日~5月20日为金牛座,5月21日~6月20日为双子座,6月21日~7月22日为巨蟹座,7月23日~8月22日为狮子座,8月23日~9月22日为处女座,9月23日~10月22日为天秤座,10月23日~11月22日为天蝎座,11月23日~12月22日为人马座,12月23日~1月20日为摩羯座,1月21日~2月20日为宝瓶座,2月21日~3月20日为双鱼座。 运行结果示例如图3-31所示。
(a) (b) (c)图3-31 计算星座的运行结果示例 实验提示: ① 此题为多分支嵌套结构,先根据月份值进行分支选择,再按照日期值进行分支选择。 ② 因为月份只有1到12这12个正整数,因此用case语句实现会更简洁。实验项目5 循环结构程序设计方法一、实验目的 (1)掌握三种循环结构:while、do…while、for的区别与联系,以及它们之间相互转换的方法,并能正确使用它们。 (2)掌握与循环语句相关的break 语句和continue 语句的使用方法。 (3)学会使用C语言循环结构编写程序。 (4)理解循环结构嵌套的格式和使用方法。二、实验要求 (1)掌握while、do…while和for语句的不同书写格式。 (2)熟悉利用while、do…while和for语句编写简单的循环程序。 (3)掌握break语句和continue语句的区别。三、实验内容 1.验证性实验 (1)3025这个数具有一种独特的性质:将它平分为二段30和25,相加后求平方即(30 25)2,恰好等于3025本身。求出具有这样性质的全部四位数,运行结果如图3-32所示。
图3-32 3025性质的四位数的运行结果 实验提示: 具有这种性质的四位数没有分布规律,可采用穷举法,从中筛选出符合条件的数。 ① 定义变量n,代表这样的四位数。 ② 四位数从1000变化到9999,对其中的每一个数都判断下是否符合这种特性。如果符合就输出,不符合就继续判断下一个数。 程序参考代码如下: #includeint main(){ int n,a,b; for(n=1000;n<=9999;n ){ a=n/100; b=n%100; if((a b)*(a b)==n) printf(“%d “,n); }printf(“n”); return 0;} ① 如果求10000以内的水仙花数,怎么做?水仙花数满足条件是这个数等于其个位数、十位数、百位数的立方和。 ② 可不可以总结出类似题目的解题规律呢? (2)输入一行字符,分别统计出其中的英文字母、空格、数字和其他字符的个数,运行结果如图3-33所示。
图3-33 统计字符个数的运行结果 实验提示: 可以使用while循环语句编程,输入一个字符,就判定一下这个字符是英文字母、空格、数字或其他字符,直到输入“n”时结束循环。 程序参考代码如下: #include int main(){ char c; int let=0,spa=0,dig=0,oth=0; while((c=getchar())!=’n’){ if(c>=’a’&&c<=’z’||c>=’A’&&c<=’Z’) let ; else if(c==’ ‘) spa ; else if(c>=’0’&&c<=’9′) dig ; else oth ; } printf(“let=%d spa=%d dig=%d oth=%dn”,let,spa,dig,oth); return 0;} 这道题还可以采取其他的写法吗?尝试所有的可能。 (3)输入一组正整数,输入?1表示输入结束,分别统计其中奇数和偶数的个数,运行结果如图3-34所示。
图3-34 统计奇偶个数的运行结果 实验提示: 可设一整型变量x,表示循环输入的整数的值,若x%2==0即为偶数,否则是奇数。循环条件可在while语句后的括号中出现,也可以用 break语句控制。 ① 声明变量xo、xj、x,xo表示偶数个数,xj表示奇数个数,x表示输入的正整数。 ② 判断x值是否为?1,不是转到第③步,若是转到第④步。 ③ 判断x值是奇数还是偶数,是奇数,xj ;是偶数,xo 。然后输入下一个x。 ④ 输出xo和xj的值。 程序代码参考一: #includeint main(){ int x,xo=0,xj=0; /*将偶数个数xo与奇数个数xj赋0值*/ scanf(“%d”,&x); /*先输入一个正整数*/ /*输入不是-1时循环*/ while(x!=-1) { if(x%2==0)xo=xo 1 ; else xj=xj 1 ; scanf(“%d”, &x); }/*循环输入其余正整数*/ printf(“xo:%d,xj:%dn”,xo,xj); return 0;} 程序代码参考二: #includeint main(){ int x,xo=0,xj=0 ; /*在循环内部用 break 语句控制循环条件*/ while(1){ scanf(“%d”,&x); if(x==-1)break ; if(x%2==0)xo=xo 1 ; else xj=xj 1 ; } printf(“xo:%d,xj:%d”,xo,xj); return 0;} 可以用do…while、for循环来实现吗? (4)编写一个程序,计算并输出a aa aaa … aaa…a(n个a)的值。其中,n由键盘输入,例如:a=2,n=3时是求2 22 222之和,运行结果如图3-35所示。
(a) (b)图3-35 a aa aaa的运行结果 实验提示: ① 这是个多项式求和问题,所以只要找出通项,通过循环,将其累加就可以了。但这个数列通项的变化规律不是简单的递增或递减,需要找出前后两项求和a之间的关系。 ② 假设t为通项式,将t设定初始值t=a,第二项为aa=t*10 a,将该数值赋给t为求第三项做准备即t=t*10 a,那么第三项aaa=t*10 a。因此这个数列的变化规律就是t=t*10 a,t初值为a。 程序参考代码如下: #includeint main(){ int n,a,t,i,s=0; printf(“请输入a和n的值:n”); scanf(“%d%d”,&a,&n); t=a; for(i=1;i<=n;i ){ s =t; t=t*10 a; }printf(“s=%dn”,s); return 0;} 大家可以总结出求数列之和的通用方法吗? (5)使用迭代法求,求立方根的迭代公式为。假定x的初值为a,迭代到|xi 1?xi|=10?5时为止。求当a=27的值,并使用系统函数pow(a, 1.0/3)加以验证,运行结果如图3-36所示。
图3-36 求立方根的运行结果 实验提示: ① 迭代法又称为递推法,其基本方法是给定一个初值,利用迭代公式反复迭代计算,直到前后两个值的绝对值小于给定的某个数值为止。 ② 输入a的值,并让x的初值为a。 ③ 通过循环反复获得xi 的值,直到|xi 1?xi|=10?5为止。 程序代码参考: #include#includeint main(){ float a, x, x1, e; printf(“a =”); scanf(“%f”, &a); x = a; while(1){ x1=2*x/3.0 a/(3.0*x*x); e=fabs(x1-x); if(e<1e-4)break; else x=x1; } printf(“x=%2.5fn”, x1); printf(“pow(%0.2f, 1.0/3)=%2.5f n”, a, pow(a, 1.0/3)); return 0;} 这道题可以改用for循环和do…while循环来实现吗? 2.设计性实验 (1)采用do…while语句编程计算π的近似值。要求:采用公式?2/6 = 1/12 1/22 1/32 …实现,直到最后一项小于10?12,定义double变量sum存储累加和,term变量存累加项,pi记录最终结果,循环变量为i,运行结果如图3-37所示。 实验提示: 这是数列求和问题,要通过循环解决,只要找出通项,随着循环的运行,将数列中的每一项都加上。 (2)编写一个程序,求出200到800之间满足下面两个条件的数:①每位上数字之 积为42;②每位上数字之和为12,并统计输出满足条件的数的个数,运行结果如图3-38所示。 图3-37 计算π的运行结果 图3-38 满足条件的数的个数的运行结果 实验提示: 用循环变量n记录数据从200变到800,然后判断每个数n是否满足上面两个条件。 (3)设计一个程序,输入一个日期,要求算出这一天是本年的第几天,运行结果如图3-39所示。 图3-39 某天是这年的第几天的运行结果 实验提示: ① 要算出某天是当年的第几天,应该将当年中本月之前所有月的天数相加,再加上本月至此的天数。 ② 但这里有一个闰年问题,2月是一个特殊月,闰年的2月有29天,非闰年的2月只有28天。那么可以先使用循环结构累加天数,然后使用分支结构计算三种类型的月份的天数,如3月为31天。 ③ 判断某年是闰年的条件是:该年号能被4整除但不能被100整除,或者能被400整除。例如,1996、2000是闰年,2014不是闰年。 (4)编写程序,输入两个不同的正整数,求其最大公约数和最小公倍数,运行结果如图3-40所示。
图3-40 求最大公约数和最小公倍数的运行结果 实验提示: 利用辗转相除法求两个整数a和b的最大公约数的算法如下: ① a%b得余数c。 ② 若c=0,则b即为两数的最大公约数。 ③ 若c≠0,则a=b,b=c,再回去执行①。 例如求27和15的最大公约数的过程为:27/15余12,15/12余3,12/3余0,因此,3即为最大公约数。 求最小公倍数算法:最小公倍数=两整数的乘积/最大公约数。 3.提高实验 (1)某人摘下一些桃子,卖掉一半,又吃了一只;第二天卖掉剩下的一半,又吃了一只;第三天、第四天、第五天都如此处理,第六天一看,发现就剩下一只桃子了。编写一个程序,求此人共摘了多少只桃子,运行结果如图3-41所示。 实验提示: 采用迭代法。 (2)编写一个程序,功能是:输入一个五位正整数,将它反向输出。例如输入12345,输出应为54321,运行结果如图3-42所示。 图3-41 猴子吃桃的运行结果 图3-42 逆序输出的运行结果 实验提示: ① 此题需要逆序取得输入的正整数的每一位上的值,依次输出。 ② 可以采用对10取余的操作求得个位上的数值。 ③ 将输入的正整数缩小至原来的1/10获得一个新的正整数,再进行对10取余,直到这个正整数变为0。实验项目6 分支与循环结构综合程序设计一、实验目的 (1)掌握C语言中的程序控制结构。 (2)掌握常见的循环结构和分支结构混合使用的程序设计方法。 (3)学会使用综合程序设计方法实现一些典型的算法以及一些实际问题。二、实验要求 (1)熟悉综合的程序设计方法,会编写稍微复杂的程序。 (2)能够掌握程序的运行步骤,尤其是循环结构程序。 (3)能够在程序中正确使用break和continue语句。三、实验内容 1.验证性实验 (1)使用C语言循环结构打印图3-43所示的图形。
图3-43 输出*的运行结果 实验提示: ① 分析图形,从中找出行数、空格数、星号数间的关系,如表3-1所示。 表3-1 行数、空格数、星号数间的关系行 数空 格 数星 号 数1 3 12 2 33 1 54 0 7i 4?i 2*i?1 ② 可用双重循环控制整个图案的输出。若用循环变量i、j分别控制外层、内层循环,则i 的取值从1到4,表示行数,在每行中要先输出4?i个空格和2*i?1个星号,然后换行。 程序代码参考: #includeint main(){ int i,j ;/*定义循环控制变量 */ for(i=1;i<=4;i ){ for(j=1;j<=4-i;j ) printf(” “); /* 输出 4-i个空格 */ for(j=1;j<=2*i-1;j ) printf(“*”); printf(“n”); } return 0;} ① 如果这个图形的行数用变量n来表示,可以从键盘输入的话,那这样输出的图形就很灵活了,试实现它。 ② 如果输出图3-44至图3-47几种图形,该怎样修改程序呢? 图3-44 *图1 图3-45 *图2 图3-46 数字图1 图3-47 数字图2 (2)分析题。 实验提示: ① 分析下面的程序,得出输出结果。 ② 输入程序,运行验证。 ③ 画出流程图。 #includeint main(){ int i,j,x=0; for(i=0;i<2;i ){ x ; for(j=0;j<=3;j ){ if(j%2) continue; x ; } x ; } printf(“x=%dn”,x); return 0;} continue语句的作用是什么? (3)分析题。 实验提示: ① 分析下面的程序,得出输出结果。 ② 输入程序,运行验证。 ③ 画出流程图。 #includeint main(){ int i=5; do{ switch(i%2){ case 4: i–; break; case 6: i–; continue; } i–; i–; printf(“%d “,i); }while(i>0); return 0;} 可以将这个程序改用for循环和while循环来实现吗? 2.设计性实验 (1)编写一个程序,求e的值,其中:,要求累加项1/n!,精确到10?12,运行结果如图3-48所示。
图3-48 求e的值的运行结果 实验提示: ① 求阶乘需要一个循环来实现,累加又需要一个循环,因此需要使用二重循环来实现。 ② 采用sum存储累加值,fac存储阶乘,外循环变量为i,内循环变量为j,累加项为item,并给sum赋初值1,循环的结束条件为最后一项小于10?12。 (2)设计一个程序,输出100~400之间的所有素数,每行输出5个,运行结果如图3-49所示。 实验提示: ① 这道题要对100~400之间的每一个数判断其是不是素数,如果是就输出它。很显然,这需要一个循环。判断一个数是不是素数时,又需要一个循环,所以这是一个二重循环的题目。 ② 用变量n记录数据从100变到400,这形成外循环,循环体是判断n是不是素数,因为需要每行输出5个,所以当n是素数时,不仅要输出n,还要进行计数。 ③ 每行输出5个数,也就是输出5个素数后换行,输出20个素数换行,30个换行,那么10,20,30等这些数据具有什么特性呢?把它总结出来,便可实现每行输出10个。 (3)验证哥德巴赫猜想:任何一个大于6的偶数都可以表示为两个素数之和。例如:6=3 3,8=3 5,…,100=3 97。要求将6~100的偶数都表示成两个素数之和,每行输出3个等式,运行结果如图3-50所示。 图3-49 输出素数的运行结果 图3-50 哥德巴赫猜想的运行结果 实验提示: 由于需要在6~100之间找出所有偶数满足条件的两个素数,故需要一个最外层的循环;判断素数需要一个最内层的循环;而验证猜想需要一个循环。故整个程序需要三重循环。判断p是否为素数可以采用p整除i=2~sqrt(p)范围中的每一个数来实现。 将一个偶数分解为两个素数的算法如下。 ① 假设num为偶数,先求出3~num/2中的一个素数,假定为p1。 ② 计算p2=num?p1。 ③ 判断p2是否为素数,如果是,则num =p1 p2(p1和p2都是素数),完成分解。 ④ 若p2不是素数,则继续在3~num/2中找下一个素数p1。重复②~④步,直到找到满足条件的两个素数为止。 (4)将一个正整数分解质因数。例如:输入60,打印出60=2*2*3*5,运行结果如图3-51所示。 实验提示: 对n进行分解质因数,应先找到一个最小的质数k,然后按下述步骤完成: ① 如果这个质数恰等于n,则说明分解质因数的过程已经结束,打印出即可。 ② 如果n<>k,但n能被k整除,则应打印出k的值,并用n除以k的商,作为新的正整数n,重复执行第①步。 ③ 如果n不能被k整除,则用k 1作为k的值,重复执行第①步。 3.提高实验 (1)用1、2、3、4这4个数字,能组成多少个互不相同且无重复数字的三位数?分别是多少?运行结果如图3-52所示。 图3-51 分解质因数的运行结果 图3-52 组成三位数的运行结果 实验提示: ① 可填在百位、十位、个位的数字都是1、2、3、4,因此使用三重循环结构。 ② 组成所有的排列后再去掉不满足条件的排列。 (2)编写一个程序,求满足如下条件的最大的n:,运行结果如图3-53所示。 实验提示: ① 定义n这个变量来计算n2,定义sum这个变量来作为的和。 ② 利用while循环和n 来计算sum的值,执行循环的条件是sum <= 1000。当sum>1000时,停止执行循环,再输出此时n?1的值。 (3)输出杨辉三角形。杨辉三角形如图3-54所示,满足如下特点:①端点的数为1。②其余每个数字等于它上一行的左右两个数字之和。③第n行的第m个数可表示为C(n-1,m-1)。④组合数计算方法:C(n,m)=n!/[m!(n-m)!] 。 图3-53 求满足最大的n的运行结果 图3-54 杨辉三角形的运行结果 实验提示: ① 找到图形中数值得来的规律。 ② 每一行的输出都是先输出空格,再输出数字。 ③ 先不考虑空格,将所有的数字靠左边输出。 ④ 将空格加上输出。实验项目7 一维数组程序设计一、实验目的 (1)掌握一维数组的定义、赋值和输入输出方法。 (2)理解一维数组定义时各部分所代表的意义,并能正确引用该数组元素。 (3)熟悉和掌握与一维数组有关的常用算法,如查找、排序等。二、实验要求 (1)理解C语言中数组的作用及应用特点。 (2)掌握一维数组元素的引用及有序性特点。 (3)理解一维数组的实际应用。三、实验内容 1.验证性实验 (1)定义一维整型数组a(包含5个元素),通过键盘输入方式对其各元素进行赋值,并求出这些元素中的最大值。 实验提示: ① 使用语句int a[5];定义数组a,通过对“scanf( “%d”, &a[i] );”语句的循环来输入各元素的值,再通过依次比较来求取元素的极值,最后输出相应的结果信息,示例结果如图3-55所示。
图355 程序运行结果一 ② 将程序中t
![插图](https://static.easterneast.com/file/easternspree/img/604d3561f0f22467a5776e87_353179.jpg)
![插图](https://static.easterneast.com/file/easternspree/img/604d3566f0f22467a5776e88_353180.jpg)
![插图](https://static.easterneast.com/file/easternspree/img/604d356bf0f22467a5776e89_353181.jpg)
![插图](https://static.easterneast.com/file/easternspree/img/604d356ff0f22467a5776e8a_353182.jpg)
![插图](https://static.easterneast.com/file/easternspree/img/604d3574f0f22467a5776e8b_353183.jpg)
![插图](https://static.easterneast.com/file/easternspree/img/604d3579f0f22467a5776e8c_353184.jpg)
评论
还没有评论。