C语言学习知识规范标准答案(删减版).doc
!-C语言答案()第一章 C语言程序设计基础习题参考答案1-1 冯诺依曼体系结构的基本原理:五大构成部分:输入、输出、CPU、控制器、存储器;程序存储、自动执行、逻辑判断功能;二进制的信息表示。1-6 编辑、编译、链接、执行。1-7 必须有一个主函数,它是程序执行的起点;一个C语言程序由函数构成;每一条可执行语句都必须由分号结束;函数的代码段必须由花括号对括住。一个函数中的语句组由声明区和可执行语句区两部分构成。1-8 三个一缩;每遇到一个结构时均缩格,每结束一个结构时回退;缩格格式必须对齐。1-9 试给出以下问题的程序设计过程描述:1) 求两个数中之最大者。#include<stdio.h>int main(void)float fA,fB;clrscr();printf("Please input two values(fA,fB):"); /*输入要比较的两个数fA,fB*/scanf("%f,%f",&fA,&fB); /*格式化输入fA,fB*/if(fA>=fB) printf("the max is %f",fA);if(fA<fB) printf("the max is %f",fB);return 0; /*main()函数结束*/2) 求三个数中之最大者。#include<stdio.h>int main(void)float fA,fB,fC,fMax;printf("Please input three values(fA,fB,fC):"); /*fA,fB,fC是输入的3个数,fMax存放最大值*/scanf("%f,%f,%f",&fA,&fB,&fC);fMax=fA;/*假定fA最大*/if(fMax<fB) fMax=fB;if(fMax<fC) fMax=fC;printf("The max is %fn",fMax);/*输出最大值*/return 0; /*main()函数结束*/3) 求1+2+3+100,即 。#include<stdio.h>int main(void)int i,nSum;/*声明变量i,循环的总和*/for(i=1,nSum=0;i<=100;i+) nSum+=i;/*做累加的FOR循环*/printf("Sum is %dn",nSum);/*输出累加值*/return 0;4) 求0-1000之间所有能被2和3整除的数之和。int main(void)int i,nSum;clrscr();for(i=1;i<=1000/6;i+)/*1000/6表示11000中能被2和3整除的个数*/ nSum+=i*6;/*循环累加的过程*/printf("the Sum is %d",nSum);/*输出累加结果*/return 0;1-12 试编写一个求a+|b|的程序。#include<stdio.h>int main(void)float a,b;printf("Please input two real values(a,b):");scanf("%f,%f",&a,&b);printf("n%f+|%f|=%fn",a,b,b>0?a+b:a-b);/*利用三元条件运算,详见P52*/return 0;1-13 试编写一个在五个整数中找出最大数的程序。#include<stdio.h>int main(void)float val_1,val_2,val_3,val_4,val_5,fMax;/*声明要比较的5个变量*/printf("Please input 3 values(val_1,val_2,val_3,val_4,val_5):");scanf("%f,%f,%f,%f,%f",&val_1,&val_2,&val_3,&val_4,&val_5);fMax=val_1;/*假设最大值为val_1*/if(fMax<val_2) fMax=val_2;if(fMax<val_3) fMax=val_3;if(fMax<val_4) fMax=val_4;if(fMax<val_5) fMax=val_5;/*选出最大值的过程*/printf("the max of %f,%f,%f,%f,%f is %f",val_1,val_2,val_3,val_4,val_5,fMax);return 0;1-14 编写程序,调用库函数求下列函数的值: (1) cos 2.78#include<stdio.h>#include<math.h>/*包含数学函数文件,详见P391*/int main(void)double val;printf("Please input the value:");scanf("%f",&val);printf("the result is %lf",cos(val);/*调用数学函数中的double cos(double x)函数*/return 0;(2) log 90#include<stdio.h>#include<math.h>int main(void)double val;printf("Please input the val:");scanf("%lf",&val);printf("the result is %lfn",log(val);return 0;(3) #include<stdio.h>#include<math.h>int main(void)double val;printf("Please input the value(val):");scanf("%lf",&val);printf("the result is %lfn",sqrt(val);/*调用double sqrt(double x)函数*/return 0;(4) #include<stdio.h>#include<math.h>int main(void)double val;printf("Please input the value(val):");scanf("%lf",&val);printf("the result is %lf",exp(val);/*调用double exp(double x)函数*/return 0;1-16 见名知义;变量名和函数名小写,符号常量一般大写;多个单词构成标识符名时,一般单词的第一个字母大写,或者用下划线连接;在不影响阅读的情况下,可以使用简单的符号变量名,如a,b,c,d,x,y,z等;注意一些容易混淆的字母的使用;匈牙利前缀数据类型表示法的运用及i,j,k,l,m,n的整型约定规则。第二章 C语言中的数据类型及其基本操作习题参考答案2-1 为什么C的每个数据都必须属于某种特定的数据类型?解:变量存储空间中的值必须属于某种特定的数据类型才有意义,同时,数据的类型不同,其取值范围、所占存储空间大小、能够参加的运算类型等才有意义。例如:一个char型数据占用一个字节空间,一个float型数据占用4个字节空间。另外,作为C语言中的数据类型,大部分都可以用signed, unsigned, long, short进行修饰,以表示数据的取值范围和数据所占存储空间的字节数变化。2-2 浮点数和定点数的区别在哪里?解:在于小数点位置是否固定不变。2-3 计算机中的数是精确的表示吗?解:不完全是。对整型数据,在不超出表示值范围时一般是精确表示的。对浮点数,则一般是不能精确表示。原因在于计算机内表示浮点数的存储空间大小是固定的,因此,它所能表示出来的精度是有限的。例如,无限循环小数3.33333333333333333333333在计算机内部只能近似表示。2-4 为测试数据类型所占存储空间的大小,C提供了专门的运算符sizeof(),它用于返回或计算给定数据变量或数据类型所占存储空间的大小。请编写程序能够测试C的基本数据类型所占存储空间的大小。解:这里以int型为例。其它数据类型所占存储空间大小的测试方法相似。#include <stdio.h>void main() int nSize=sizeof(int); printf("%d",nSize); getch();2-9为什么要强调“先声明、后定义、再使用”的原则?请阐述其理由。解: 因为变量使用前必须要有存储空间分配给它用来保存其值,对变量存储空间的分配就是通过变量的声明完成的。变量在被引用之前,其中的值应当是确定的某一个值,但变量的声明并不能保证变量存储空间中有一个合适的初始状态值,而是一个随机值。当以错误的初始值开始变量的引用时,会导致程序的执行逻辑错误。为此,一般需要在变量被引用之前赋予其一个合理的初始值。因此,在变量的使用上,一般应当遵循先声明、后定义、在引用的基本原则。2-12 解:(1)ABC DEFGH(2)12+20=32(3)ch1(S)+ch2(x)=203(4)nX=2 nY=5 nZ=12nX=1830 nY=28 nZ=38nX=3 nY=6 nZ=22-13 解: (1)1; (2)0; (3)0; (4)0; (5)2,2,5; (6)10; (7)3; (8)12,8,30,20,0,0; (9)15,5,324;2-14 解:m=0 n=0 k=-1m=1 n=1 k=-1m=0 n=0 k=0m=0 n=0 k=1m=1 n=0 k=12-15 解:(1)m>n&&k<=m|n;(2)m=2k;(3)m%n!=0;2-17 请问C语言中的逻辑真和假的表示方法是什么?解:.C语言借用数值非零和零表示逻辑真假,零表示假,任何非零值均可被作为逻辑真。2-18 解:.i=9,j=28第三章 C语言的程序结构、语句分类和数据的输入输出习题参考答案3-1 解:因为输入、输出是计算机程序获取源数据和输出结果数据的基本手段。没有输入操作,程序无法将数据对象告知计算机,没有输出时,计算机程序的运算对于计算任务来讲是没有意义的。C语言常见的输入输出函数如下:scanf(.);fscanf(.);fread(.);printf(.);fprintf(.);fgets(.);gets(.);.3-2 解:格式说明符、普通字符、输出格式控制字符、附加格式说明符。域宽:用於存放输出数据的宽度。格式化输入输出函数的主要异同参见教材相关章节。3-3 解:对小数部分截断输出(四舍五入的原则)对整数部分没有影响;与截断位的精度相同;有单独的符号位;符号位不占据域宽。3-4 解:float:小数点后面6位小数位;double:小数点后面17位小数位。原因:float占4个byte,其中能够用来表示小数位精度的bit位数只有23bit。 而double占8个byte,其中能够用来表示小数位精度的bit位数为52bit。它们能够表示的最大有效精度范围分别为6位和17位小数位。多余的精度部分将被截断。同时,要注意,浮点数表示中,小数点不占域宽宽度。3-5 解:C语言主要由模块、函数等构成。其语句的分类有5种(参见教材)。3-6 请简述C语言程序的语句类型分类并对其使用方法作简要描述。解:顺序语句如:int main(void)int a=8;printf(”%d”,a);return 0; 循环语句:while()for(;)选择语句:如switch();if()等语句;3-7 请说明使用格式化输入语句完成输入任务时和输入缓冲区之间的关系。解:scanf是从标准输入设备缓冲区数据流中自动根据内部格式控制字符串要求完成数据类型匹配,并把数据从左到右复制到参数列表变量地址空间的函数,其过程分为以下几个步骤:(1) 函数执行时由标准输入设备(一般是键盘)输入相关数据,临时存放在标准输入设备缓冲区中;(2) scanf函数从数据流中复制数据从左到右一次匹配于变量列表中的各变量;(3) scanf向调用函数返回成功接收数据的个数。3-8 解:在输入多个数值数据时,若格式控制串中没有非格式字符作输入数据之间的间隔则可用空格,TAB或回车作间隔。C编译在碰到空格,TAB,回车或非法数据(如对“%d”输入“12A”时,A即为非法数据)时即认为该数据结束。3-9 解:100#123.456001 123.4561.23e+02000123.456001.23e+02-123.457*-123.456780*-1.23457e+02*-123.456780$#100#1003-10 解:ch is e:dec=101 oct=145 hex=65 ASCII=ei is 101:dec=101 oct=145 hex=65 ASCII=ech is x:dec=120 oct=170 hex=78 ASCII=xi is -4:dec=-4 oct=177774 hex=fffc ASCII= 3-11 解:12345 378901 2345 6789i=12 j=6789x=345.000000 y=901.000000ch=3-12 解:printf(“m=%d n=%d k=%dn”,m,n,k);printf(“x=%f y=%f z=%fn”,x,y,z);printf(“x+y=%.2f y+z=%.2f z+x=%.2fn”,(int)x-y,y+z,-z-(int)x);printf(“u=%-9u n=%9ld”,u,n);printf(“ch1=%c or %dn”,ch1,ch1);printf(“ch2=%c or %dn”,ch2,ch2);3-13 解:4,3,3,2从右往左开始算3-14 请分析和给出以下程序段的输出结果。 #include <stdio.h> int main(void) /*主函数*/ int i=59;float fX;double dY,dZ;printf("i =%dn",i);printf("i =%5dn",-i);printf("i =%5on",i);printf("i =%5xn,i");printf("i =%ldn",i);fX=dY=333.12345678901234567890;dZ=-555.1234567890123456789e-9;printf("%fn",fX);printf("%fn",dZ);printf("%en",dZ);printf("%.4fn",fX);printf("%.8fn",dY);printf("%.3en",dZ);printf("%.18fn”,dY);printf("%10.3en",dY);printf("%2.5fn",dY);printf("%2en",dZ);rerturn 0; /*main()函数结束*/ (分析略)。3-15编写一个程序显示如下的方框,椭圆,箭头,或者菱形图* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * int main(void)printf("*n");printf("* *n");printf("* *n");printf("* *n");printf("* *n");printf("* *n");printf("*n");return 0; /*其余的照例或者用for循环来做*/3-17 int main()int num;int square11;int cube11;for(num=0; num<=10; num+)squarenum = num * num;cubenum = num * num * num;printf("number square cuben");printf("-n");for(num=0; num<=10; num+)printf("%-10d %-10d %-10dn", num, squarenum, cubenum);return 0;第四章 程序设计的算法基础习题参考答案4-1 试分析给出人们日常生活中对问题求解的一般过程和步骤。解:首先:(必须)知道一些已知条件或约束条件;第二,确定或寻找针对该问题的求解方法;第三,根据选择的求解方法确定具体的问题求解步骤;第四,进行问题求解的实际演算和推理活动;最后,得到并整理求解结论。4-2解:(1)1)睁开双眼; 2)穿好衣服、裤子及鞋子等;3)下床; 4)洗漱(包括洗脸、刷牙等);5)吃早餐(包括饭后洗碗等工作); 6)上课学习; 7)吃午餐; 8)午休;9)上课学习;10)吃晚餐; 11)课外活动(包括看电视、写作业等等);12)洗漱;13)上床; 14)脱衣服、裤子及鞋子等;15)睡觉。 (2)1)整理好课本;2)从座位上站起来;3)走出教室;4)走进食堂; 5)排队;6)判断是否已经轮排到自己,若否,则转5),否则转7); 7)刷卡;8)点菜、买饭。 (3)1)寻找座位;2)坐下; 3)用筷子夹起饭菜; 4)将饭菜送到嘴里; 5)细嚼慢咽; 6)判断是否已经吃饱或者饭菜已经吃完,若否,则转7),否则转8); 7)重复3)5)过程;8)整理餐具,从座位上站起;9)端起餐具离开座位; 10)寻找水龙头,洗碗;11)带着餐具回寝室;12)到达寝室,放下餐具; 13)做个人卫生;14)午睡;4-4 怎么理解Wirth提出的程序=算法+数据结构的深刻含义?解:程序是在数据的某种特定表示方法和结构基础上对抽象算法的具体描述,它揭示了面向过程程序设计的本质。将程序设计问题分为算法和数据结构,充分显示了算法在程序设计过程中的重要性。算法注重问题求解的过程和步骤描述,主要考虑问题求解的方法;程序是对算法具体实现的描述,它需要考虑与程序语言及编程环境有关的实现细节,如语言环境、操作系统环境等。4-5解:参见课本第79页。4-6解:算法的实质是对问题求解方法和过程的描述,它由解决问题的基本操作及控制操作过程次序的控制结构组成。其中基本操作包括算术、关系、逻辑等基本运算和输入输出以及函数、位操作、文件操作等;控制结构主要是顺序、选择和循环三种基本的控制结构。算法的三组成要素:1)操作; 2)控制结构; 3)数据结构;算法的基本性质:1)(有穷)动作序列; 2)动作序列只有一个起点(即初始动作); 3)每一动作只有一个后继动作; 4)动作序列的终止表示问题得解或无解(不保证一定能得解)。4-7解:算法描述方法有:1) 传统流程图和标准流程图符号体系的表示方法;2) 传统流程图符号表示的结构化表示方法;3) 无流程线流程图符号的结构化表示方法;4) 问题分析图的结构化表示方法;5) 伪代码的结构化程序表示方法。传统流程图符号是一些专门设计的图形符号,用于表示程序或算法中的各类操作,用线条表示这些操作之间的执行顺序。标准流程图符号是针对传统流程图符号体系的改进。在算法描述中使用他们来描述算法过程,能很好地表达程序设计的结构与梗概,方便同人的交流。传统流程图运用起来灵活、自由、形象、直观,流程线指向的任意转向使得绘制过程比较随意、自由,易被接受和运用。但是流程线的不加限制带来了算法流程绘制的随意性和不规则性容易导致绘制出来的流程图零乱,阅读不变,修改和维护也比较困难。无流程线流程图显得更紧凑和清晰,其结构化绘制具有强迫性,绘制结构化流程图的过程也更加容易和方便,克服了传统流程图的缺陷,同时保留了流程图的直观和简单特点。但是该表示法的图形嵌套层次不能太多,尤其是对多层次条件选择的嵌套清形,并且对图形的修改和维护,也不如传统流程图方便。问题分析图PAD采用PAD图形符号描述算法,比较方便,当问题过程复杂时PAD描述方法优势更为明显,同时它克服了传统流程图的随意和非结构化特征,也避免了N-S图随嵌套层次的增加内层矩形框急剧缩小所带来的表述上的不方便。伪代码的结构化程序表示方法,比基于图形符号的方法自由度大,同时它可以使用自然语言和程序语言进行比较自由的算法描述,可以不严格遵守程序语言的严格语法约束,另外,由于直接使用了程序语言的要素,在算法的程序语言实现时更加的方便。但它要遵守结构化描述这一基本的要求。4-8 C语言提供了哪些用于结构化程序设计的基本技术?解:C语言提供了3种用于结构化程序设计的基本技术,分别是:1)顺序;2)选择;3)循环。 4-11 对例4-8的方法2和方法3,试分析并给出其流程图描述。N-S流程图(方法2_逐一比较):程序代码:#include<stdio.h>int main(void) float fa,fb,fc,max; /声明fa,fb,fc,max四个变量. clrscr(); /清屏. printf("please input three values(fa,fb,fc):"); scanf("%f,%f,%f",&fa,&fb,&fc); /依次输入fa,fb,fc的值. if(fa<fb) /如果fa<fb if(fb<fc) /并且,如果fb<fc,则max=fc;max=fc; else /否则,max=fb;max=fb; else /否则 if(fa<fc) /并且,如果fa<fc,则max=fc;max=fc; else /否则,max=fa;max=fa; printf("the max is %fn",max); /输出fa,fb,fc三个数的最大值max. return 0;运行测试结果: N-S流程图(方法3_两两比较): 程序代码:#include<stdio.h>int main(void) float fa,fb,fc,temp,max; /声明fa,fb,fc,temp,max五个变量. clrscr(); /清屏. printf("please input three values(fa,fb,fc):"); scanf("%f,%f,%f",&fa,&fb,&fc); /依次输入fa,fb,fc的值. if(fa<fb) /如果fa<fb,将fb的值赋给中间变量temp,即temp=fb;temp=fb; else /否则,将fa的值赋给temp,即temp=fa;temp=fa; if(temp>fc) /如果中间变量temp>fc,则将temp的值赋给max,即max=temp;max=temp; else /否则,将fc的值赋给max,即max=fc;max=fc; printf("the max is %fn",max); /输出fa,fb,fc三个数的最大值max. return 0;运行测试结果:4-12 对例4-9所示的流程图(图4-8),请分析其算法执行步骤过程。解:1)给出参数n的值;2)如果 ,转3);否则转4);3)如果 ,输出n值非法的提示信息,然后转7);否则转6);4)初始化fac=1;i=1;然后转5);5)计算n!的值:即当 ;求出n!的值fac,然后转7);6)fac=1,然后转7);7)输出n!的值(n非法时写非法)4-15 解:阶梯共有119步。问题分析:设阶梯数为steps,则依据题意有: .由此,知道steps整除7,且为正整数,那么steps的最小取值至少为7,因而我们假定其初始值为7,即初始化steps=7;N-S流程图: 传统流程图: 程序代码:#include<stdio.h>int main(void) int steps=7; /初始化 clrscr(); /清屏 while(1) /当为真时 if(steps%2=1&&steps%3=2&&steps%5=4&&steps%6=5&&steps%7=0) break; /如果满足上述公式,则退出while循环.else steps+; /否则,steps加1,继续while循环. printf("there are %d steps!n",steps); /输出求解结果:阶梯数目steps. return 0;运行测试结果:4-16 解:算法描述:1)输入一个门限值 ,及精确值e,并初始化:i=1;sum=0; 2)计算i!; 3)计算1/i!; 4)对1/i!累计求和; 5)判断求解的误差(e-sum)是否小于门限值 ; 6)若是,则转7);否则,做i+,然后转2); 7)输出满足条件时i的取值.传统流程图: 伪代码:#include<stdio.h>int main(void) float e; float eps; float fac=1; float sum=0; int i=1; /声明及初始化 clrscr(); /清屏 printf("please input the eps and e(eps,e):"); scanf("%f,%f",&eps,&e); /输入门限值 =eps,及精确值e; while(e-sum)>=eps) /当精确值与近似值间误差大于门限值时 fac*=i; /求i!; printf("the %d fac is %fn",i,fac); /输出i!的值fac; sum+=1/fac; /对i!的倒数累加求和 i+; /i自加1; /输出满足误差小于门限值时的n的值(i-1); printf("when the error is less than %f,the n is %dn",eps,i-1); return 0;运行测试结果: 4-18 解:问题分析:对于本次绿化活动的树苗费用,由于每棵树苗的价格一定(为8元),那么只要确定了绿化所栽的树苗总数就行了,而所用树苗总数又取决于树与树之间的间距以及道路的全长,这两个因素都是确定的,因此我们可以先求出单侧大道绿化所需树苗数,再乘以2,即得到所需树苗总数,然后乘以单棵树苗价格,即该次绿化活动树苗费用。问题求解假设:假定r_length表示大道全长,r_length=2000米(1公里=1千米),t_price表示单棵树苗价格,t_price=5元/棵,spacing表示树苗间距,spacing=5米。传统流程图: 程序代码:#include<stdio.h>int main(void) /*变量声明,r_length,price,spacing分别表示大道长度,树苗单价,树苗间距*/ int r_length,t_price,spacing; int i=0,j=0,sum=0; /*j记录单侧大道绿化所需树苗数*/ clrscr(); /清屏 printf("please input the information(r_length,t_price,spacing):"); scanf("%d %d %d",&r_length,&t_price,&spacing); /*依次输入大道长度、树单价、树间距.*/ for(i=0;i<=