第一篇:C语言程序设计教程(第2版)课后习题答案杨路明
第一章 C语言程序设计概述 -习题答案1 算法的描述有哪些基本方法? 答
1、自然语言
2、专用工具
C语言程序的基本结构是怎样的?举一个例子说明。
答
1、C语言程序由函数构成;
2、“/*”与“*/”之间的内容构成C语言程序的注释部分;
3、用预处理命令#include、#define可以包含有关文件或预定义信息;
4、大小写字母在C语言中是有区别的;
5、除main()函数和标准库函数外,用户也可以自己编写函数,应用程序一般由多个函数组成,这些函数指定实际所需要做的工作。3 C语言有什么特点?
答
1、具有结构语言的特点,程序之间很容易实现段的共享;
2、主要结构成分为函数,函数可以在程序中被定义完成独立的任务,独立地编译代码,以实现程序的模块化;
3、运算符丰富,包含的范围很广;
4、数据类型丰富;
5、允许直接访问物理地址,即可直接对硬件进行损伤,实现汇编语言的大部分功能;
6、限制不太严格,程序设计自由度大,这样使C语言能够减少对程序员的束缚;
7、生成的目标代码质量,程序执行效率高,同时C语言编写的程序的可移植性好。4 ★指出合法与不合法的标识符命名。答
AB12--√ leed_3--a*b2--× 8stu--× D.K.Jon--× EF3_3--√ PAS--√ if--× XYZ43K2--√ AVE#XY--× _762--√ #_DT5--× C.D--× 5 说明下列Turbo C热键的功能。答
F2:源文件存盘 F10:调用主菜单 F4:程序运行到光标所在行(用于调试程序)Ctrl+F9:编译并链接成可执行文件 Alt+F5:将窗口切换到 DOS 下,查看程序运行结果。说明下列Turbo C方式下输入并运行下列程序,记录下运行结果。
①main()
{printf(“********************n”);printf(“ welcome you n”);printf(“ very good n);printf(”********************n“);} ②main()
{ int a,b,c,t;printf(”please input three numbers;“);scanf(”%d,%d,%d“,&a,&b,&c);/*教材S是错误的*/ t=max(max(a,b),c);printf(”max number is:%dn“,t);} int max(int x, int y){ int z;if(x>y)z=x;else z=y;return(z);} 答
运行结果:
******************** welcome you very good ******************** 运行结果:
please input three numbers;3,1,4 /*左侧下划线内容为键盘输入*/ max number is:4 7 一个C程序是由若干个函数构成的,其中有且只能有一个___函数。
答
main()8 在Turbo C环境下进行程序调试时,可以使用Run下拉菜单的___命令或按___键转到用户屏幕查看程序运行结果。
答
1、User screen
2、Alt+F5 9 ★C语言对标识符与关键字有些什么规定?
答
1、标识符用来表示函数、类型及变量的名称,它是由字母、下划线和数字组成,但必须用字母或下划线开头。
2、关键字是一种语言中规定具有特定含义的标识符,其不能作为变量或函数名来使用,用户只能根据系统的规定使用它们。C源程序输入后是如何进行保存的?
答
是以C为扩展名保存的纯文本文件。
第二章 C语言程序的基本数据类型与表达式 -习题答案 ★指出下列常数中哪些是符合C语法规定的。
答
''--× '101'--× ”“--× e3--× 019--√ 0x1e--√ ”abn“--√ 1.e5--×(2+3)e(4-2)--× 5.2e2.5--× 请找出下列程序中的错误,改正后写出程序运行结果。
①void main()
{int x,y=z=5,aver;x=7 AVER=(x+y+z)/3 printf(”AVER=%dn“,aver);} ②void main()
{ char c1='a';c2='b';c3='c';int a=3.5,b='A' printf(”a=%db='“endn”,a,b);printf(“a%cb%cbc%ctabcn”,c1,c2,c3);} 答
main(){int x,y=5,z=5,aver;x=7;aver=(x+y+z)/3;printf(“AVER=%dn”,aver);} 运行结果:AVER=5 ②main()
{ char c1='a', c2='b', c3='c';int a=3,b='A';printf(“a=%d,b='%c'”end“n”,a,b);printf(“a%cb%cbc%ctabcn”,c1,c2,c3);} 运行结果:a=3,b='A'“end”
aabcc abc 3 写出下列赋值的结果,表格中写了数值的是要将它赋给其他类型的变量,将所有的空格填上赋值后的数据(实数保留到小数点后两位)。int 99
-1 char
'h'
unsigned int
float
55.78
long int
答 int 99 104 66 55 68-1 char 'c' 'h' 'B' '7' 'D'
unsigned int 99 104 66 55 68 65535 float 99.00 104.00 66.00 55.78 68.00-1.00
long int 99 104 66 55 68-1
★写出程序运行结果。
①void main(){int i,j;i=8,j=10;printf(“%d,%d,%d,%dn”,i,j,++i,j++);} ②main()
{ int a=1,b=2,c=30;;printf(“%d,%d,%d,%dn”,a=b=c,a=b==c,a==(b=c),a==(b==c));} 注意:a=b=c,a=b==c之间应为逗号,教材有误
答
运行结果: 9,11,9,10 运行结果: 30,1,0,0
③void main()
{int a=10,b=20,c=30,d;d=++a<=10||b-->=20||c++;printf(“%d,%d,%d,%dn”,a,b,c,d);}
答
运行结果: 11,19,30,1
★写出下面表达式的值(设a=10,b=4,c=5,d=1,x=2.5,y=3.5)。⑴a%=(b%=3)
⑵n++,a+=a-=a*=a ⑶(float)(a+c)/2+(int)x%(int)y ⑷a*=b+c ⑸++a-c+b++ ⑹++a-c+++b ⑺a
⑼a+b,18+(b=4)*3,(a/b,a%b)
⑽x+a%3*(int)(x+y)%2/4+sizeof(int)⑾a
答
⑴0 ⑵0 ⑶9.500000 ⑷90 ⑸10 ⑹10 ⑺'A' ⑻2 ⑼4.5 ⑽1 ⑾0 ⑿20 ⒀0 下列每组表达式中,被执行后结果完全等价的是哪些(设a、b、m是已被赋值的整型变量)?
①m=(a=4,4*5)与m=a=4,4*5 ②(float)(a/b)与(float)a/b ③(int)a+b与(int)(a+b)④m%=2+a*3与m=m%2+a*3 ⑤m=1+(a=2)+(b=3)与a=2,b=3,m=1+a+b 答
①前面是赋值表达式,而后面的是一个逗号表达式,所以一定不同;
②前面的表达式中a/b结果为一整数,结果已经取整,精度可能受到影响,之后强制float后才为浮点型,后面的是先将a转换为float后再与b相除,其值保证了精度,所以不同。③因为a、b均为整数,其前后两个表达式的计算结果是一致的。
④前一表达式是一算术表达式,而后者为一赋值表达式,此为一点不同;另外,前一表达式的m只被赋过一次值,后一表达式中的m曾两次被赋值,第一次赋值时与第一表达式中的值一致,第二次赋值后即不再相同。
⑤前后表达式的计算结果应该是一致的:a=2, b=3, m=6 7 条件表达式x>0?x:-x的功能是什么?
答
如果x的值是一正数,则表达式的值为x值;如果x的值是一非正数,则表达式的值为-x。其实该表达式的值即为x的绝对值,C语言中提供了一个函数fabs(x)即可完成此功能,该函数包含在math.h头文件中。用一个条件表达式描述从a、b、c中找出最大都赋给max.答
max=a>(b>c?b:c)?a:(b>c?b:c);9 ★若x为int型变量,则执行以下语句后x的值为()。x=6;x+=x-=x*x;A.36 B.-60 C.60 D.-24 答 B.10 ★若有以下类型说明语句:
char w;int x;float y;double z;则表达式w*x+z-y的结果为()类型。A.float B.char C.int D.double 答 D.第三章 顺序结构程序设计 -习题答案 变量k为float类型,调用函数scanf(“%d”,&k),不能使变量k得到正确数值的原因是___。
答
格式修饰符与变量类型不一致。因为%d输入的数据类型应该为十进制整数,而&k为占用4个字节的float类型变量的地址。★a=1234,b=12,c=34,则执行“printf(“|%3d%3d%-3d|n”,a,b,c);”后的输出是___。
答
|1234 1234 | 分析如下:
①%3d为右对齐输出变量,且指定输出变量的值宽度为3个字符位,如果变量实际位数小于3,则左端补空格,如果变量实际位数大于3,则按实际长度输出,不受限制。
②%-3d为左对齐输出变量,在输出变量时,如是变量实际位数小于3,则在右端补空格,否则按实际输出。★设有“int a=255,b=8;”,则“printf(“%x,%on”,a,b);”输出是___。答 ff,10 ①如果“printf(“%X,%on”,a,b);”则输出为FF,10。说明在输出十六进制字母时,其大小写受格式修饰符的限制,如果是“%x”则输出小写,如果是“%X”则输出大写。②如果希望在输出十六进制时输出前导符0x或0X,则以上输出语句应改“printf(“%#x,%on”,a,b);”为或“printf(“%#X,%on”,a,b);”。本条解释不必须掌握。★以下程序输出的结果是___。main(){ int a1=1,a2=0,a3=2;printf(“%d,%d,%dn”,a1,a1+a2+a3,a3-a1);} 答 1,3,1 5 printf函数中用到格式符%5s,其中5表示输出字符占用5列。如果字符串长度大于5,则按___输出;如果字符串长度小于5,则按___输出。
答
①实际 ②左端补空格 6 ★已定义变量如下: int a1,a2;char c1,c2;若要求输入a1、a2、c1和c2的值,正确的输入函数调用语句是___。
答
scanf(“%d,%d,%c,%c”,&a1,&a2,&c1,&c2);7 输入两个整型变量a、b的值,输出下列算式以及运算结果___。a+b、a-b、a*b、a/b、(float)a/b、a%b 每个算式占一行。如a=10,b=5,a+b输出为:10+5=15 答
设int a=10,b=5;以下为输出语句及结果:
①printf(“%d+%d=%dn”,a,b,a+b);10+5=15 ②printf(“%d-%d=%dn”,a,b,a-b);10-5=5 ③printf(“%d*%d=%dn”,a,b,a*b);10*5=50 ④printf(“%d/%d=%dn”,a,b,a/b);10/5=2 ⑤printf(“%(float)d/%d=%fn”,a,b,(float)a/b);(float)10/5=2.000000 ⑥printf(“%d%%%d=%dn”,a,b,a%b);10%5=0 8 ★输入一个非负数,计算以这个数为半径的圆周长和面积。答
#define PI 3.1415926 main(){ float r,l,area;printf(“Input a positive:”);scanf(“%f”,&r);l=2*PI*r;area=PI*r*r;printf(“l=%ftarea=%fn”,l,area);} 9 输入任意一个3位数,将其各位数字反序输出(例如输入123,输出321)。
答
main(){ int x,y;printf(“Input a number(100-999):”);scanf(“%d”,&x);y=100*(x%10)+10*(x/10%10)+x/100;/*注意分析此处算法*/ printf(“%d--->%dn”,x,y);} 10 ★输入任意大小的3个整数,判断其中是否有两个奇数一个偶数。若是则输出YES,不是则输 出NOT(要求用条件表达式进行判断,不使用if语句)。
答
main(){ int x,y,z,oddcount=0;/*奇数数计数变量*/ printf(“Input x,y,z:”);scanf(“%d,%d,%d”,&x,&y,&z);x%2==1?oddcount++:0;y%2==1?oddcount++:0;z%2==1?oddcount++:0;oddcount==2?printf(“YES”):printf(“NOT”);} 11 求前驱字符和后继字符。输入一个字符,找出它的前驱字符和后继字符,并按ASCII码值,按从大到小的顺序输出这3个字符及其对应的ASCII码值。
答
本题考查同学们对字符类型数据的认识,如果在ASCII范围内则即可以显示为字符,又可以显示为整数值;无论是否能够显示为字符,字符类型数据是可能参与数值运算的,切记。main(){ char c;printf(“Input character:”);scanf(“%c”,&c);printf(“%c----->%dn”,c-1,c-1);printf(“%c----->%dn”,c,c);printf(“%c----->%dn”,c +1,c+1);getch();/*为便于调试程序,运行至此程序停顿,此时可以看到运行结果,按任意键程序真难得结束并返回到编辑环境*/ } 12 ★输入三角形的边长,求三角形面积(面积=sqrt(s(s-a)(s-b)(s-c)),s=(a+b+c)/2)。
答
#include“math.h” /*由于程序中使用了开平方函数sqrt(),所以需要包含数学头文件*/ main(){ float a,b,c,s,area;int ok=0;printf(“Input a,b,c:”);scanf(“%f,%f,%f”,&a,&b,&c);a+b>c?ok++:0;/*以下3条语句为判断是否输入的数据是否构成封闭三角形*/ a+c>b?ok++:0;b+c>a?ok++:0;ok==3?(s=(a+b+c)/2,area=sqrt(s*(s-a)*(s-b)*(s-c)),printf(“area=%f”,area)):printf(“error”);getch();}
第四章 选择结构程序设计 -习题答案 ★设x、t均为int型变量,则执行语句“x=10;t=x&&x>10;”后,t的值为___。
答 0 2 ★假定所有变量均已正确定义,则程序段: int a=0, y=10;if(a=0)y--;else if(a>0)y++;else y+=y;运行后 y 的值是___;
答 20 3 ★能表述 20 x>20&&x<30||+x<-100 4 ★若有定义语句“int a=25,b=14,c=19;”,则以下语句执行结果是___。if(a<=25 && b<=2 && c)printf(“***a+b=%d, a-b=%d***n”, a+b, a-b);else printf(“***a=%d, b=%d, c=%d***n”,a, b, c);答 ***a=25, b=14, c=19*** 5 ★假定 i 和 j 为 int 型变量,则执行以下语句后 i 的值是___。int i=1;switch(i){ case 1: { for(j=0;j<9;j++)i+=j;break;} case 2: { for(j=1;j<10;j++)i+=j;break;} case 3: i++;} 答 37 分析:执行了case 1: 和case 3: 中的代码。同时case 1:语句中的{ }是可以取消的。★以下两条 if 语句可合并成一条 if 语句,即___。 if(a<=b)x=1;else y=2;if(a>b)printf(“***y=%dn”, y);else printf(“***x=%dn”,x);答 if(a<=b)printf(“***x=%dn”,x=1);else printf(“***y=%dn”, y=2);7 ★输入两个字符,若这两个字符的序号(ASCII码)之差为偶数,则输出它们的后继字符,否则输出它们的前驱字符。 答 main(){ char a,b;printf(“Input two chatacter a,b:”);scanf(“%c,%c”,&a,&b);if((a-b)/2==0)printf(“%c,%c”,a+1,b+1);else printf(“%c,%c”,a-1,b-1);} 8 ★输入整数 a 和 b,如果 a 能被 b 整除,就输出算式和商,否则输出算式、整数商和余数。答 main(){ int a,b;printf(“Input two integer numbers a,b:”);scanf(“%d,%d”,&a,&b);if(b!=0&&a%b==0)printf(“%d/%d=%d”,a,b,a/b);else printf(“%d/%d=%d......%d”,a,b,a/b,a%b);} 9 输入某个点 A 的平面坐标(x,y),判断(输出)A点是在圆内、圆外还是在圆周上,其中圆心坐标为(2,2),半径为 1。 答 include“math.h” main(){ float x,y,d;printf(“Input x,y:”);scanf(“%f,%f”,&x,&y);d=sqrt((x-2)*(x-2)+(y-2)*(y-2));if(d>1)printf(“outside”);else if(d<1)printf(“inside”);else printf(“inside”);} 10 ★输入年号和月份,输出这一年该月的天数(一个年份,先判断是否闰年)。 答 main(){ int y,m,d,f;printf(“Input year and month y-m:”);scanf(“%d-%d”,&y,&m);f=(y%4==0&&y/100!=0||y/400==0);if(m==2)d=28+f;/*依据是否闰年决定2月份的实际天数,若是闰年,则f=1,d即为29天*/ else d=31-(m==4)+(m==6)+(m==9)+(m==11);/*m==4时其值为1,则本月为30天,典型算法,重要啊*/ printf(“%d-%d is %d days.n”,y,m,d);} 11 ★请将以下语句改写成 switch 语句(a>0)。if(a<30)m=1;else if(a<40)m=2;else if(a<50)m=3;else if(a<60)m=4;else m=5 答 switch(a/10){ case 1: case 2: case 3:m=1;break;case 4:m=2;break;case 5:m=3;break;case 6:m=4;break;default:m=5;} 12 有一函数 x-1-5 答 使用不嵌套的 if 语句程序如下: main(){ float x,y;printf(“Input x:”);scanf(“%f”,&x);if(x>-5&&x<0)y=x-1;if(x==0)y=0;if(x>0&&x<8)y=x+1;printf(“y=%fn”,y);} 使用嵌套的 if 语句程序如下: main(){ float x,y;scanf(“%f”,&x);if(x>-5&&x<8)if(x<0)y=x-1;else if(x==0)y=0: else y=x+1;printf(“y=%fn”,y);} main()float x,y;scanf(“%f”,&x);if(x<8)if(x>0)y=x+1;else if(x==0)y=0;else if(x>-5)y=x-1;printf(“y=%fn”,y);} 使用多分支语句程序如下: main(){ float x,y;int m;printf(“Input x:”);scanf(“%f”,&x);if(x>-5&&x<8)if(x<0)m=-1;else if(x==0)m=0: else m=1;switch(m){ case-1:y=x-1;break;case 0:y=0;break;case 1:y=x+1;break;} printf(“y=%fn”,y);} 以下为假设对int类型的变量进行处理,但毕竟不算完美 main(){ int x,y;printf(“Input x:”);scanf(“%d”,&x);switch(x){ case-4: case-3: case-2: case-1: y=x-1;break;case 0: y=0;break;case 1: case 2: case 3: case 4: case 5: case 6: case 7: y=x+1;break;} printf(“y=%dn”,y);} 第五章 循环结构程序设计 -习题答案 ★输入 n 个整数,求这 n 个数之中的偶数平均值,并输出。 答 main(){ int n,i,x,sum=0,count=0;printf(“Input n:”);scanf(“%d”,&n);for(i=0;i 答 #include“stdio.h” main(){ char ch;int charcnt=0,numcnt=0;while((ch=getchar())!='*'){ if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')charcnt++;if(ch>='0'&&ch<='9')numcnt++;} printf(“Characters number:%dnDigits number:%dn”,charcnt,numcnt);getch();} 3 ★从键盘输入一个正整数 n,计算该数的各位数字之和并输出。例如,输入数是5246,则计算5+2+4+6=17并输出。答 #include“stdio.h” main(){ int n,i,sum=0,count=0;printf(“Input n:”);scanf(“%d”,&n);while((n/10)!=0){ count++;sum+=n%10;printf(“%d+”,n%10);n/=10;} printf(“=%d”,sum+n);getch();} 4 ★输入一个字符串,将其中的大写字母改为小写字母,小写字母改为大写字母,然后输出。 答 #include“stdio.h” main(){ char ch;printf(“Input string:”);while((ch=getchar())!='n'){ if(ch>='a'&&ch<='z')printf(“%c”,ch-32);if(ch>='A'&&ch<='Z')printf(“%c”,ch+32);} getch();} 5 设某县2000年工业总产值为200亿元,如果该县预计平均年工业总产值增长率为4.5%,那么多少年后该县年工业总产值将超500亿元。 答 main(){ float x=200;int n=0;do { x*=(1+0.045);n++;}while(x<500);printf(“n=%d”,n);getch();} 6 ★输出1~999中能被3整除,而且至少有一位数字是5的所有数字。答 main(){ int x,y,flag;for(x=1;x<1000;x++){ flag=0;y=x;if(y%3==0)/*余数为0说明该数能够被3整除*/ { while(y%10!=0){ if(y%10==5)flag=1;/*依个位、十位、百位顺序判断是否余数为5*/ y/=10;} if(flag==1)printf(“%dt”,x);} } getch();} 7 求爱因斯坦数学题。有一条长阶,若每步跨2阶,则最后剩1阶,若每步跨3阶,则最后剩2阶,若每步跨5阶,则最后剩4阶每步跨6阶,则最后剩5阶每步跨7阶,最后正好1阶。 答 main(){ int x=0,flag=0;while(1){ x++;if(x%2==1)if(x%3==2)if(x%5==4)if(x%6==5)if(x%7==0){ printf(“%d”,x);break;} } getch();} 8 输入一个3位数,判断是否是一个“水仙花数”。水仙花数是指3位数的各位数字的立方和等于这个3位数本身。例如,153=1*1*1+5*5*5+3*3*3 答 main(){ int x,a,b,c;printf(“Input number:”);scanf(“%d”,&x);a=x/100;/*变量a中记录x的百位数字*/ b=x/10%10;/*变量b中记录x的十位数字*/ c=x%10;/*变量c中记录x的个位数字*/ if(a*a*a+b*b*b+c*c*c==x){ printf(“%d=%d*%d*%d+%d*%d*%d+%d*%d*%dn”,x,a,a,a,b,b,b,c,c,c);printf(“YES”);} else printf(“NOT”);getch();} 9 ★计算斐波那契分数序列前n项之和(n是某个常数,波那契分数序列为2/1,3/2,5/3,8/5,...)。 答 main(){ int i,n=10;float f1=1,f2=2,f,sum=0;for(i=0;i 答 main(){ int n,i,j;printf(“Input n:”);scanf(“%d”,&n);for(i=0;i 答 main(){ int i,j;for(i=1;i<=9;i++){ for(j=1;j<=i;j++)printf(“%d*%d=%-3d”,j,i,i*j);printf(“n”);} getch();} 12 输入一串字符,直到输入一个星号为止,统计(输出)其中的正整数和负整数个数以及所有正整数的平均值和所有负整数的平均值。 答 #include“stdio.h” #include“math.h” main(){ char ch;int x=0,y=1,f=0,pcnt=0,ncnt=0;float psum=0,nsum=0;while((ch=getchar())!='*'){ if(ch=='-'){ if(x!=0){ if(f==1){ x=-x;nsum+=x;ncnt++;} else { psum+=x;pcnt++;} printf(“%dn”,x);} f=1;x=0;y=1;continue;} else if(ch>='0'&&ch<='9'){ x=10*x+ch-'0';y=10*y;if(x!=0&&10*x 答 main(){ int k1, k2, k3, k4, k5, k6, k7, k8, k9, k10;int i,a,n,s;for(a = 100;a <= 999;a++){ n = 0;/* n累计因子的个数 */ s = a;/* s存放未求出的因子之和,初值为被测数本身 */ for(i = 1;i < a;i++)if(a % i == 0)/* 由i到a循环检测i是否为a的因子 */ { n++;/* 找到一个因子 */ s = s-i;/* 减去已找到的因子 */ switch(n)/* 将找到的因子赋绐k1, k2,...*/ { case 1 : k1 = i;break;case 2 : k2 = i;break;case 3 : k3 = i;break;case 4 : k4 = i;break;case 5 : k5 = i;break;case 6 : k6 = i;break;case 7 : k7 = i;break;case 8 : k8 = i;break;case 9 : k9 = i;break;case 10 : k10 = i;break;} } if(s == 0)/* 已经找到全部因子 */ { printf(“%d Its factors are ”, a);if(n > 1)printf(“%d,%d”, k1, k2);/* n>1表示a至少有2个因子 */ if(n > 2)printf(“,%d”, k3);/* 注意以下if的用法,追加的方法 */ if(n > 3)printf(“,%d”, k4);if(n > 4)printf(“,%d”, k5);if(n > 5)printf(“,%d”, k6);if(n > 6)printf(“,%d”, k7);if(n > 7)printf(“,%d”, k8);if(n > 8)printf(“,%d”, k9);if(n > 9)printf(“,%d”, k10);printf(“n”);} } getch();} 14 ★编写程序按下列公式计算e的值(精度为1e-6)。e=1+1/1!+1/2!+1/3!...+1/n!答 main(){ int i;double e=0,t=1;for(i=1;t>0.000001;i++){ for(j=1;j<=i;j++)t*=j;t=1/t;e+=t;} printf(“e=%fn”,e);getch();} 15 用二分法求方程2x3-4x2+3x=0在(-10,10)附近的根(二分法:先找到a、b,使f(a)、f(b)异号,说明在区间(a,b)内一定有零点,然后求f[(a+b)/2],现在假设f(a)<0,f(b>0,a 答 #include“math.h” main(){ double x,fx,fa,fb,a=-10,b=10,z=0.0001;fa=2*a*a*a-4*a*a+3*a;fb=2*b*b*b-4*b*b+3*b;if(fa*fb<0){ do { x=(a+b)/2;fx=2*x*x*x-4*x*x+3*x;if(fx<0){ a=x;fa=2*a*a*a-4*a*a+3*a;} else { b=x;fb=2*b*b*b-4*b*b+3*b;} }while(fabs(fa-fb)>z);printf(“The root is:%lfn”,x);} getch();} 第六章 函数与编译预处理 -习题答案 ★写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果。两个整数由键盘输入。 答 main(){ unsigned int m,n,p,q;for(;;){ printf(“m,n=”);scanf(“%d,%d”,&m,&n);if(m<0||n<0){printf(“The end.n”);break;} p=funp(m,n);q=funq(m,n);printf(“p(%d,%d)=%dnq(%d,%d)=%dn”,m,n,p,m,n,q);} } int funp(int m,int n){ int i;if(m>n){i=m;m=n;n=i;} for(i=m;i>0;i--)if(m%i==0&&n%i==0)return(i);} int funq(int m,int n){ int i;if(m 答 未制作函数,主要利用了选择语句结构: #include“stdio.h” main(){ int i,c,zm=0,sz=0,kg=0,qt=0;printf(“Input a string:”);while((c=getchar())!='n')if(c==' ')kg++;else if(c>47&&c<58)sz++;else if(c>='A'&&c<='Z'||c>='a'&&c<='z')zm++;else qt++;printf(“am=%d,sz=%d,kg=%d,qt=%dn”,zm,sz,kg,qt);} 制作函数,利用函数调用: #include“stdio.h” int analys(char ch);main(){ int i,zm=0,sz=0,qt=0,c;printf(“Input a string:”);while((c=getchar())!='n'){ i=analys(c);switch(i){ case 1: zm++;break;case 2: sz++;break;case 3: qt++;} } printf(“zm=%d,sz=%d,qt=%dn”,zm,sz,qt);} int analys(char ch){ if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')return 1;if(ch>47&&ch<58)return 2;return 3;} 3 ★按照第5章第8题的要求编写判断水仙花数的函数,从主函数输入正整数n,在主函数中调用判断水仙花数的函数,找出n以内所有的水仙花数。 【输入一个3位数,判断是否是一个“水仙花数”。水仙花数是指3位数的各位数字的立方和等于这个3位数本身。例如,153=1*1*1+5*5*5+3*3*3】 答 main(){ int x,i,f;printf(“Input number:”);scanf(“%d”,&x);for(i=0;i<=x;i++){ f=0;f=fun(i);if(f==1)printf(“%dt”,i);} getch();} int fun(int x){ int a,b,c;a=x/100;b=x/10%10;c=x%10;if(a*a*a+b*b*b+c*c*c==x)return 1;else return 0;} 4 ★定义一个宏,实现将两个数互换,并写出程序,输入两个数作为使用参数,并显示结果。 答 #define f(a,b)(a=a+b,b=a-b,a=a-b)main(){ int x,y;printf(“Input x,y:”);scanf(“%d,%d”,&x,&y);printf(“%d,%d”,x,y);f(x,y);printf(“<-->%d,%dn”,x,y);getch();} 5 已知二阶Fibonacci数列: 0 若n=0 Fib(n)= 1 若n=1 Fib(n-1)+Fib(n-2)其它情况 定义递归函数求Fib(n)。 答 main(){ int i,n;printf(“Input n:”);scanf(“%d”,&n);for(i=0;i<=n;i++)printf(“%dt”,fib(i));getch();} int fib(int n){ if(n==0)return 0;else if(n==1)return 1;else return(fib(n-1)+fib(n-2));} 6 定义函数求F=(n+m)!+n!,m、n均为任意正整数。要求使用递归调用。 答 long int f(int x);main(){ int i,m,n;long int sum;printf(“Input m,n:”);scanf(“%d,%d”,&m,&n);sum=f(n+m)+f(n);printf(“%ld”,sum);getch();} long int f(int x){ int i,j;if(x==0||x==1)return 1;else return(x*f(x-1));} 7 ★定义一个函数完成第5章第11题的功能。【输出九九乘法表。】 答 main(){ fun();getch();} fun(){ int i,j;for(i=1;i<=9;i++){ for(j=1;j<=i;j++)printf(“%d*%d=%-3d”,j,i,i*j);printf(“n”);} } 8 如果有两个数,每一个数的所有约数(除了它本身以外)的和正好等于对方,则称这两个数为互满数,求出30000以内所有的互满数,并显示输出,求一个数它的所有约数(除了它本身以处)的和,用函数实现。 答 main(){ int x,y;for(x=1;x<30000;x++){ for(y=1;y 答 ★设计程序完成下列计算。 已经:y=f(x,n)/(f(x+2.3,n)+f(x-3.2,n+3))其中:f(x,n)=1-x2/2!+x4/4-...+(-1)n·x2n/(2n)!(n≥0)当: x=5.6, n=7时,求:y 要求通过嵌套调用完成计算。 答 #include { y*=x;} return y;} float f2(int m){ int i;float y=1;for(i=1;i<=m;i++){ y*=i;} return y;} 第七章 数 组 -习题答案 ★以下各题中,选择一个正确的答案。 1、能正确对一维数组 a 中所有元素进行初始化的是()。 A.int a[5]={ } B.int a[ ]={0} C.int a[5]=0,0,0,0,0 D.int a[5]={0} 2、有说明 int k=3,a[10];则下列可以正确引用数组元素的表达式是()。A.a[k] B.a[10] C.a[1,3] D.a[3*5] 3、有定义 int d[ ][3]={1,2,3,4,5,6};执行语句printf(“%c”,d[1][0]+'A');结果是()。 A.A B.B C.D D.E 4、有定义 char c='A',ch[20]={'a','b','c',' ','d',' '};若执行printf(“%s”,ch);结果是()。 A.'abc' B.abc C.abcd D.abc d 5、对数组进行初始化 char carr[ ]={'s','t','u','d','e','n','t'},barr[ ]=“student”;则正确的是()。 A.carr 与 barr 长度相同 B.carr 比 barr 长 C.carr 与 barr 相同 D.carr 比 barr 短 答 1、BD 2、A 3、D 4、B 5、D 2 ★阅读下列程序,写出程序的执行结果。 1、#include 2、若输入十进制数3291时,下列程序输出为: #include 1、从键盘输入一个数,将其插入到一个升序数组中,保持数组仍然按升序排列。#include for(k=8;____②____;k--)if(a[k] for(k=0;__⑤__;k++)printf(“%7d”,a[k]);} 2、从键盘输入一串英文字符(不含空格与其他字符),统计每个字符的个数,并输出字母及相应的个数。 #include 1、① a[8]=data ② k>=1 ③ temp=a[k] ④ break ⑤ k<=8 2、① “%s” ② str[i]<='Z' ③ c[str[i]-'a'+26]++ ④ i+'A' ★求一组成绩的平均分数以及高于平均分的成绩,设给定的成绩为 90,85,92,77,80,62。答 main(){ int score[6]={90,85,92,77,80,62};int i,sum=0;float aver;for(i=0;i<6;i++)sum+=score[i];aver=sum/6.0;printf(“nAverage:%fn”,aver);printf(“High score:”);for(i=0;i<6;i++)if(score[i]>aver)printf(“%dt”,score[i]);} 5 ★编写程序,输入一组整数,将它们排序后由小到大输出。 【提示】假设为具有 10 个元素的正整数数组;外层循环从数组的第一个元素开始选取;内层循环从外层循环选定的元素下一个元素开始选取,依次与外层循环选定的元素进行比较,将小者放入外层循环选定的元素中。 答 #define N 10 main(){ int a[N],i,j,t;for(i=0;i #define M 4 main(){ int a ; int i,j,k,t;printf(“Input integer number:n”);for(i=0;i for(j=0;j { printf(“a[%d][%d]=”,i,j);scanf(“%d”,&a[i][j]); } for(i=0;i { for(j=0;j { printf(“%dt”,a[i][j]); } printf(“n”); } printf(“-----------n”);/*分隔线*/ for(i=0;i { for(j=0;j { if(a[j][i]>a[i][j]) { t=a[j][i];a[j][i]=a[i][j];a[i][j]=t; } } for(j=i;j { printf(“%dt”,a[i][j]); } printf(“n”);for(k=0;k } getch(); } 【运行结果】 a[0][0]=1 a[0][1]=2 a[0][2]=3 a[0][3]=4 a[1][0]=5 a[1][1]=6 a[1][2]=7 a[1][3]=8 a[2][0]=9 a[2][1]=10 a[2][2]=11 a[2][3]=12 a[3][0]=13 a[3][1]=14 a[3][2]=15 a[3][3]=16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16-----------1 5 9 13 6 10 14 11 15 16 7 通过键盘给 3×4 的二维数组输入数据,然后分别按行和按列输出数组元素。 答 #define M 3 #define N 4 main(){ int a [N],i,j;printf(“Input integer number:n”);for(i=0;i { printf(“a[%d][%d]=”,i,j);/*提示输出元素位置*/ scanf(“%d”,&a[i][j]); /*为指定元素赋值*/ } printf(“nOut by row:n”);/*按行输出数组元素值*/ for(i=0;i printf(“%d ”,a[i][j]);printf(“nOut by collum:n”);/*按列输出数组元素值*/ for(i=0;i printf(“%d ”,a[j][i]); getch(); } 【运行结果】 Input integer number: a[0][0]=1 a[0][1]=2 a[0][2]=3 a[0][3]=4 a[1][0]=5 a[1][1]=6 a[1][2]=7 a[1][3]=8 a[2][0]=9 a[2][1]=10 a[2][2]=11 a[2][3]=12 Out by row: 1 2 3 4 5 6 7 8 9 10 11 12 Out by collum: 1 5 9 2 6 10 3 7 11 4 8 12 8 编写程序,将两个字符串连接起来,不要使用 strcat 函数。 答 #include“string.h” main(){ char str1[80],str2[80];int i=0,l1;printf(“Input str1:”);gets(str1);/*若换成scanf(“%s”,str1);后面应该增加fflush(stdin);函数语句*/ printf(“Input str2:”);gets(str2);l1=strlen(str1);/*计算字符串 1 的长度*/ while(str2[i]){ str1[l1+i]=str2[i];i++;} str1[l1+i]=' ';/*字符串连接后,不能忘记追加一个字符串结束符*/ puts(str1);/*可换成语句:printf(“%s”,str1);*/ getch();} 9 输入一行字符串,统计该字符串中字符对 ab 的个数。 答 #include“string.h” main(){ char str[80];int i=0,count=0;printf(“Input string:”);gets(str);while(str[i]){ if(str[i]=='a' && str[i+1]=='b'){ count++;i+=2;/*如果在当前 i 的位置找到一对,则 i 越过 b 个字母*/ } else i++;/*如果在当前 i 的位置未找到,则 i 指向下一个字母*/ } printf(“%d”,count);getch();} 10 从键盘输入 10 个字符串,找出一个最长的字符串。 答 #include“string.h” main(){ char str[10][80];/*设置二维字符数组,每一维可以记录最大79个字符的字符串*/ int i,len,k[10],n=0,max=0;printf(“Input 10 strings:n”);for(i=0;i<10;i++)/*向 str 数组输入 10 个字符串*/ { printf(“String %d=”,i+1);gets(str[i]);len=strlen(str[i]);/*计算输入之字符串之长度*/ if(len>max){max=len;n=0;k[n]=i;} /*记录最长字符串的长度、个数、在数组位置(行)*/ else if(len==max)k[++n]=i;/*与已记录最大长度相同时,记录其在数组中位置(行)*/ } if(n==0)/*此时说明只有一个最大长度字符串,是 str[k[0] */ { printf(“The longest string is String %d:”,k[0]+1);/*输出其序号*/ puts(str[k[0]]);} else /*此时说明有不止一个最大长度字符串时需要处理的复合语句*/ { printf(“Not only one!n”);for(i=0;i<=n;i++)/*分别输出各序号、字符串*/ { printf(“These are String %d:”,k[i]+1);puts(str[k[i]]);} } getch();} 已知数组 a 中有 m 个按升序排列的元素,数组 b 中有 n 个按降序排列的元素,编程将 a 与 b 中的所有元素按降序存入数组 c 中。 【提示】将 a 中的元素最大值与 b 中元素最大值相比,将最大值存入 c 数组中,然后调整 c、a 或 b 元素指针(地址),依次重复前序工作,即可。 答 #define M 3 #define N 7 main(){ int i=0,j=0,n=0,c[M+N],a[3]={10,27,543},b[7]={300,210,173,96,55,34,13};int maxa,maxb;do { maxa=a[M-i-1];maxb=b[j];if(maxa>maxb){ c[n++]=maxa;/*将 a 中最大元素赋值给 c 数组当前元素,并调整 c 新元素位置*/ i++;/*调整 a 中元素位置*/ } else { c[n++]=maxb;/*将 a 中最大元素赋值给 c 数组当前元素,并调整 c 新元素位置*/ j++;/*调整 b 中元素位置*/ } printf(“%d ”,c[n-1]);/*打印输出 c 中新赋值元素数据*/ }while(n 针 -习题答案 1 ★选择题。 1、若函数 f 定义如下: void f(char *d,char *s);{while(*d++=*s++);} 函数 f 的功能是()。 A.串比较 B.串复制 C.求串长 D.串反向 2、有定义 int arr[10]={0,1,2,3,4,5,6,7,8,9}, *p, i=2;若执行语句: p=arr;pritnf(“%d”,*(p+i));输出结果为()。 A.0 B.2 C.3 D.1 ★ 3、有定义 int td[ ][3]={1,2,3,4,5,6};以下几种方法中,不能正确表示 i 行 j 列元素的是()。 A.td[i][j] B.*(td[i]+j)C.*(*(td+i)+j)D.*(td+i-j)本题不要求掌握 答 1、B 2、B 3、D 2 ★写出下列程序的运行结果。 1、void main(){ int a,*p1,*p2;a=10;p1=&a;p2=p1;printf(“The Value is %d||%d||%dn”,a,*p1,*p2);*p1=11;printf(“The Value is %d||%d||%dn”,a,*p1,*p2);} 2、若输入字符串 program 时,写出下列程序输出结果: #include 1、The Value is 10||10||10 The Value is 11||11||11 2、ss 3 ★填空题 1、下面程序完成从键盘输入两个字符串 a 和 b,再将 a 和 b 的对应位置字符中的较大者存放在数组 c 中,填空完善该程序。#include 2、以下程序从键盘输入10个不相同的数到数组 a 中,再输入一个数到 x 中,在 a 中查找与 x 值相同的元素所在的位置,填空完善该程序。#include scanf(“%d”,____②___);printf(“Input x:”);scanf(“%d”,&x);*a=x;i=10;while(x!=*(a+i))_____③_____ if(_____④_____)printf(“%6d's position is:%3dn”,x,i);else printf(“%6d Not be found!n”,x);/*bee应为be,教材有误,小case*/ } 答 1、① *p!=' '&&*q!=' ' ② *p>*q ③ q++ 2、① i<1 1② &a[i] ③ i--;④ i>0 编写函数 fun,函数的功能是,从字符串中删除指定的字符。同一字母的大、小写按不同字符处理。例如,程序执行时输入字符串为 turbo c and borland c++,从键盘输入字符 n,则输出后变为 turbo c ad borlad c++。如果输入的字符在字符串中不存在,则字符串照原样输出。【提示】 答 #include“string.h” main(){ char s[80],*pstr=s,chdel;printf(“Input source string:”);gets(pstr);printf(“Character you want delete:”);scanf(“%c”,&chdel);fun(pstr,chdel);printf(“After deleted:”);puts(pstr);getch();} int fun(char *s,char ch){ int i,j;for(i=0,j=0;s[i];i++)if(s[i]!=ch)s[j++]=s[i];s[j]=0;} 5 编程将从键盘输入的每个单词的第一个字母转换为大写字母,输入时各单词必须用空格隔开,用“.”结束输入。【提示】。 答 【解法一】 #include“stdio.h” int fun(char *p);main(){ int i=0;char ch,str[80];printf(“Input string end by.: n”);while((ch=getchar())!='.')str[i++]=ch;str[i++]='.';str[i]=' ';fun(str);puts(str);getch();} int fun(char *p){ int flag=1;while(*p!=' '){ if(*p==' ')flag=1;if(*p>='a'&&*p<='z'&&flag==1){*p-=32;flag=0;} p++;} } 【解法二】 #include“stdio.h” main(){ int flag=1;char ch;printf(“Input string end by.: n”);do { ch=getchar();flag=fun(&ch, flag);putchar(ch);}while(ch!='.');printf(“n”);} fun(char *c,int f){ if(*c==' ')return 1;else { if(f&&*c<='z'&&*c>='a')*c-=32;return 0;} } 6 从键盘输入 8 个数,用选择法按由大到小的顺序排列并输出,要求用指针实现。【提示】 答 #include“stdio.h” #include“string.h” main(){ int data[80],i,*p1,*p2,temp;p1=data;printf(“Input 8 numbers:”);for(i=0;i<8;i++)scanf(“%d”,p1++);for(p1=data;p1 答 #include“string.h” #include“stdio.h” main(){ char str1[80],str2[80];int m,n,len;printf(“Input string:”);len=strlen(gets(str1));printf(“Input m,n:”);scanf(“%d,%d”,&m,&n);if(m>len||n>len-m){printf(“m,n error!”);exit(0);} else fun(str1,str2,m,n);puts(str2);getch();} fun(char *s,char *p,int x,int y){ int i;for(i=0;i 答 main(){ int a[8],i,*p,max,min,t;max=min=0;p=a;printf(“Input 8 numbers:”);for(i=0;i<8;i++)scanf(“%d”,&a[i]);for(i=1;i<8;i++)if(*(p+i)<*(p+min))min=i;if(min!=7){ t=*(p+7);*(p+7)=*(p+min);*(p+min)=t;} for(i=1;i<8;i++)if(*(p+i)>*(p+max))max=i;if(max!=0){ t=*(p+0);*(p+0)=*(p+max);*(p+max)=t;} for(p=a;p 答 #include“stdio.h” sort(int **p, int n){ int *t,i,j;for(i=0;i 输入一个字符串,内含数字和非数字字符,如 gs 423cd156 7896>? df12345,将其中连接的数字作为一个整数,依次存放到数组 a 中,例如,423放入a[0],156放入a[1],„。统计其共有多少个整数,并输出这些数。 答 未做 #include“string.h” main(){ char str[10][80];/*设置二维字符数组,每一维可以记录最大79个字符的字符串*/ int i,len,k[10],n=0,max=0;printf(“Input 10 strings:n”);for(i=0;i<10;i++)/*向 str 数组输入 10 个字符串*/ { printf(“String %d=”,i+1);gets(str[i]);len=strlen(str[i]);/*计算输入之字符串之长度*/ if(len>max){max=len;n=0;k[n]=i;} /*记录最长字符串的长度、个数、在数组位置(行)*/ else if(len==max)k[++n]=i;/*与已记录最大长度相同时,记录其在数组中位置(行)*/ } if(n==0)/*此时说明只有一个最大长度字符串,是 str[k[0] */ { printf(“The longest string is String %d:”,k[0]+1);/*输出其序号*/ puts(str[k[0]]);} else /*此时说明有不止一个最大长度字符串时需要处理的复合语句*/ { printf(“Not only one!n”);for(i=0;i<=n;i++)/*分别输出各序号、字符串*/ { printf(“These are String %d:”,k[i]+1);puts(str[k[i]]);} } getch();} C语言程序设计教程 杨路明 课后习题答案 北京邮电大学出 版社 第一章 1、算法描述主要是用两种基本方法:第一是自然语言描述,第二是使用专用工具进行算法描述 2、c语言程序的结构如下: ①c语言程序由函数组成,每个程序必须具有一个main函数作为程序的主控函数。②“/*”与“*/”之间的内容构成c语言程序的注释部分。③用预处理命令#include可以包含有关文件的信息。④大小写字母在c语言中是有区别的。 ⑤除main函数和标准库函数以外,用户可以自己编写函数,程序一般由多个函数组成,这些函数制定实际所需要做的工作。例如: void main()int a,b,c,s;a=8;b=12;c=6;s=a b*c;printf(“s=%d”,s); 3、c语言的特点: ①c语言具有结构语言的特点,程序之间很容易实现段的共享; ②c语言的主要结构成分为函数,函数可以在程序中被定义完成独立的任务,独立地编译成代码,以实现程序的模块化。 ③c语言运算符丰富,运算包含的范围很广; ④c语言数据类型丰富。 ⑤c语言允许直接访问物理地址,即可直接对硬件进行操作,实现汇编语言的大部分功能; ⑥c语言语法限制不太严格,程序设计自由度大,这样是c语言能够减少对程序员的束缚; ⑦用c语言编程,生成的目标代码质量高,程序执行效率高,可移植性好; 4、合法标识符:AB12、leed_ 3、EF3_ 3、_762、PAS、XYZ43K2 不合法标识符:a*b2、8stu、D.K.Jon、if、ave#xy、#_DT5、C.D 5、F2:将当前编辑器中文件存盘 F10:调用主菜单 F4:程序运行到光标所在行 Ctrl F9:当前编辑环境下,进行编译、连接且运行程序; Alt F5:将窗口切换到DOS下,查看程序运行结果 6、(1): ******************** welcome you very good ********************(2): please input three number;5,7,8 max number is:8 7、main 8、User screen、Alt F5 9、标识符必须是字母或下划线开头,大小写字母含义不同。由数字、字母和下划线组成; 关键字是一种语言中规定具有特定含义的标识符。关键字不能作为变量或函数名来使用,用户只能根据系统的规定使用它们。 10、选择主菜单File项下拉子菜单中Save项或直接按F2键存盘。 第二章 1、符合C语法规定的常数为:0x1e、“ab”、1.e5 2、(1): 错误如下:int x,y=5,z=5,aver;x=7;aver =(x y x)/3;结果如下:AVER=5(2): 错误如下:char c1='a',c2='b',c3='c';printf(“a=?=__end”,a,b);结果如下:a=3b='A'“end” aabcc abc3、4、(1):9,11,9,10(2):3,1,0,0(3):11,19,31,1 5、(1):0(2):0(3):9.500000(4):90(5):10(6):10(7):65(8):4(9):4.500000(10):1(11):0(12):20(13):0 6、(5) 7、求x的绝对值 8、c>(max=a>b?a:b)?c:max; 9、B 10、D 第三章 1、输入函数scanf的参数错误,应该为:scanf(“%f”,&k); 2、|1234 1234 | 3、ff10 4、1,3,1 5、原字符串 左边加空格再加字符串本省,字符个数总和为5个 6、scanf(“%d,%d,%c,%c”,&a1,&a2,&c1,&c2); 7、printf(“a b=%d”,a b);printf(“a-b=%d”,a-b);printf(“a*b=%d”,a*b);printf(“a/b=%d”,a/b);printf(“(float)a/b=%f”,(float)a/b);printf(“a%b=%d”,a%b); 8、void main()float r;float s,c;printf(“please input the number:”);scanf(“%f”,&r);if(r>=0)s = 3.14*r*r;c = 2*3.14*r;printf(“s = %f, c = %f”,s,c);else printf(“you input number is error!”); 9、void main()int n;printf(“please input the number:”);scanf(“%d”,&n);if(n>=100 && n printf(“%d%d%d”,n_,(n/10)_,n/100);else printf(“you input number is error!”); 10、void main()int i,j,k;scanf(“%d,%d,%d”,&i,&j,&k);((i%2!= 0?1:0)(j%2!= 0?1:0)(k%2!= 0?1:0))== 2?printf(“YES”):printf(“NO”); 11、void main()char a;scanf(“%c”,&a);printf(“%c,%c,%c”,a-1,a,a 1);printf(“%d,%d,%d”,a-1,a,a 1); 12、void main()float a,b,c,s,Area;scanf(“%f,%f,%f”,&a,&b,&c);if(a b > c || a c > b || b c >a)s =(a b c)/2;Area = sqrt(s*(s-a)*(s-b)*(s-c));printf(“%f”,Area);else printf(“you input the number is error!”); 第四章 1: 0 2: 20 3:(x20)||(x 4: ***a=25,b=14,c=16*** 5: 37 6: if(a else printf(“2”); 7、#include void main()char a,b,t1,t2;scanf(“%c,%c”,&a,&b);t1=a>b?a:b;t2=a if((t1-t2)%2==0)printf(“%c,%c”,a 1,b 1);else printf(“%c,%c”,a-1,b-1);getch(); 8、#include void main()int temp1=0,temp2=0,x,y,i=1;printf(“Please input(x,y): ”);scanf(“%d,%d”,&x,&y);while((i*y)if(x==(i*y))temp1=1;break;temp2=i;i;if(temp1)printf(“%d / %d = %d”,x,y,i);else printf(“%d / %d---> shang=%d,yushu=%d”,x,y,temp2,x-y*temp2);getch(); 9、#include void main()float x,y,m=0,n=0;scanf(“%f,%f”,&x,&y);n=(x-2)*(x-2);m=(y-2)*(y-2);if((m n)printf(“(%.3f,%.3f)In the yuan”,x,y);else printf(“(%.3f,%.3f)out of the yuan”,x,y);getch(); 10、#include void main()int temp=0,month,year;printf(“Please input(year,month): ”);scanf(“%d,%d”,&year,&month); if((year@0==0)||(year%4==0&&year_0!=0))temp=1;if(month==2)if(temp)printf(“%d year %d month have 29 ”,year,month);else printf(“%d year %d month have 28 ”,year,month);else if(month%2==0)printf(“%d year %d month have 30 ”,year,month);else printf(“%d year %d month have 31 ”,year,month);getch(); 11、switch(a/10)case 5:m=4;break;case 4:m=3;break;case 3:m=2;break;case 2:m=1;break;default:m=5; 12、方法一: #include void main()int x,y;scanf(“%d”,&x);if(x-5)y=x-1;else if(x==0)y=x;else if(x>0&&x y=x 1;printf(“%d”,y);getch();方法二: #include void main()int x,y;scanf(“%d”,&x);if(x-5)if(x==0)y=x;else if(x>0&&x else y=x-1;printf(“%d”,y);else printf(“Input error!!”);getch();方法三: #include void main()int x,y,i;scanf(“%d”,&x);if(x-5)if(x==0)i=1;else if(x>0&&x else i=3;else i=4;switch(i)case 1:y=x;printf(“%d”,y);break;case 2:y=x 1;printf(“%d”,y);break;case 3:y=x-1;printf(“%d”,y);break;case 4:printf(“Input error!”);break;getch(); 第五章 1、void main()int n,value;int i,count=0;float average = 0;long int sum = 0;scanf(“%d”,&n);for(i = 0;i scanf(“%d”,&value);if(value%2 == 0)sum =value;count;average = sum /(float)count;printf(“the average is %f”,average); 2、#include “stdio.h” void main()char ch;int zm = 0, sz = 0;ch = getchar();while(ch!= '*')if((ch >= 'A' && ch = 'a' && ch zm;if(ch >= '0' && ch sz;ch = getchar();printf(“zm = %d;sz = %d”,zm,sz); 3、void main()long i_value;int sum = 0;int temp = 0;scanf(“%ld”,&i_value);if(i_value for(;;)temp = i_value_;i_value = i_value/10;sum =temp;printf(“%d ”,temp);if(i_value == 0)break;printf(“=%d”,sum); 4、#include “stdio.h” void main()char ch;ch = getchar();while(ch!= '.')if((ch >= 'A' && ch ch = ch 32;putchar(ch);else if((ch >= 'a' && ch ch = ch1;printf(“Total steps: %d”, steps);return 0; 8、main()int i,j,k,n;printf(“the narcissus number is:”);for(n=100;n i=n/100;j=n/10-i*10;k=n_;if(i*i*i j*j*j k*k*k==n)printf(“%d”,n); 9、main()float i,j,temp,n,sum;int t;i=2;j=1;sum=0;scanf(“%d”,&t);for(n=1;n sum=sum i/j;temp=i;i=i j;j=temp;printf(“2/1 3/2 5/3 8/5 13/8...=%f”,sum); 10、void main()int nWidth,a,b;scanf(“%d”,&nWidth);for(a=(nWidth%2);a for(b=0;b char chOut =' ';int nleft =(nWidth-a)/2;int nright =(nWidth a)/2;if(b>=nleft&&b chOut ='*';printf(“%c”,chOut);printf(“");r 11、void main()int i=1,j=1;for(i=1;i for(j=1;j printf(”%d*%d=%d“,i,j,i*j);printf(”“) 12、#include ”stdio.h“ void main()char c;//count1是正数的个数 //count2是负数的个数 int count1=0,count2=0;//sum1是正数之和 //sum2是负数之和 int sum1=0,sum2=0;int flage = 0;c=getchar();while(c!= '*')if(c == '-')flage = 1;if(flage == 0)sum1 =(c-48);count1;else if(c!= '-')sum2-=(c-48);flage=0;count2;c = getchar();printf(”%d,%d“,count1,count2);printf(”%f,%f“,sum1/count1,sum2/count2); 13、void main()int i,j;int s = 0;for(i = 100;i s = 0;for(j=1;j if(i%j == 0)s = s j;if(s == i)printf(”]“,i); 14、#include #include void main()int n;long k = 1;float e = 1;n = 1;clrscr();while(fabs(1.0/k)>= 0.000001)n;e = e 1.0/k;k = k * n;printf(”%f“,e); 15、#include ”math.h“ main()float x0,x1,x2,f0,f1,f2;x1=-10;f1=2*x1*x1*x1-4*x1*x1 3*x1;x2=10;f2=2*x2*x2*x2-4*x2*x2 3*x2;do x0=(x1 x2)/2;f0=2*x0*x0*x0-4*x0*x0 3*x0;if((f0*f1)x2=x0;f2=f0;else x1=x0;f1=f0;while(fabs(f0)>1e-6);printf(”______2*x*x*x-4*x*x 3*x=0______:n“);printf(”the root is %f“,x0); 第六章 1、#include int divisor(int a,int b)int r;while((r=a%b)!=0)a=b;b=r;return b;int multiple(int a,int b)int d;d=divisor(a,b);return a*b/d;void main()int a,b,c,d;printf(”intput(a,b): “);scanf(”%d,%d“,&a,&b);c=divisor(a,b);d=multiple(a,b);printf(”=%d=%d“,c,d); 2、#include void tongji(char a[])int b[3]=0,0,0,i=0;while(a[i]!='')if((a[i]=65)||(a[i]=97))b[0];else if(a[i]=48)b[1];else b[2];i;printf(”zimu have: %d;shuzi have: %d;qita have: %d“,b[0],b[1],b[2]);getch();void main()char a[100];printf(”Please input a string: “);gets(a);tongji(a); 3、#include int flower(int n)int x=0,i,j,k;i=(n_);j=(n/10_);k=(n/100);x=i*i*i j*j*j k*k*k;if(x==n)return 1;else return 0;void main()int i,n;printf(”Please intput n: “);scanf(”%d“,&n);if(n>999||n else for(i=100;i if(flower(i))printf(”%d “,i);getch(); 4、#include #define SWAP(a,b)t=b;b=a;a=t;main()float x,y,t;printf(”Enter two number(x,y): “);scanf(”%f,%f“,&x,&y);SWAP(x,y);printf(”:x=%f,y=%f“,x,y);getch(); 5、#include int fib(int n)int p;if(n==0)p=0;else if(n==1)p=1;else p=fib(n-1)fib(n-2);return p;void main()int n;printf(”Please input fib: “);scanf(”%d“,&n);printf(”=%d“,fib(n)); 6、#include long fac(int n)long f;if(n==0)f=1;else f=n*fac(n-1);return f;void main()int m,n;long f;printf(”Please input(m,n): “);scanf(”%ld,%ld“,&m,&n);f=fac(n m)fac(n);printf(”=%ld“,f); 7、#include void list()int i,j;for(i=1;i for(j=1;j printf(”%d*%d=%d “,i,j,i*j);printf(”“);void main()list(); 8、#include int he(int n)int i,s=0;for(i=1;i if(n%i==0)s =i;return s;void main()int i,j;for(i=1;i for(j=1;j if((he(i)==j)&&(he(j)==i)&&(i!=j))printf(”%d%d “,i,j); 9、#include #define max 100 struct work long sid;char name[15];worker[max];int size=0;struct work *set_list()do printf(”input(sid,name): “);scanf(”%ld,%s“,&worker[size].sid,worker[size].name);size;while(worker[size-1].sid!=0);return worker;void paixu(struct work a[])int i,j,k;long t;char v[15];for(i=0;i k=i;for(j=i;j if(a[i].sid>a[j].sid)k=j;if(k!=i)t=a[i].sid;a[i].sid=a[j].sid;a[j].sid=t;strcpy(v,a[i].name);strcpy(a[i].name,a[j].name);strcpy(a[j].name,v);for(i=0;i printf(”sid: %ld:%s“,a[i].sid,a[i].name);getch();void select(struct work a[])int i=0,found=1;long num;printf(”Input select sid: “);scanf(”%ld“,&num);for(i=0;i if(a[i].sid==num)found=0;printf(”%ld: %s“,num,a[i].name);break;if(found)printf(”this sid!!“);getch();void main()struct work *p;p=set_list();paixu(p);select(p); 10、#include float jiecheng(int n)long s=1;int i;for(i=1;i s=s*i;return s;float chengfang(float x,int n)float s=1;int i;for(i=1;i s=s*x;return s;float f(float x,int n)float s=1,t=0;int i=1,j=-1;for(i=1;i t=j*chengfang(x,2*i)/jiecheng(2*i);s =t;j=j*j;return s;main()float s1=0,s2=0,s3=0,s4=0,x=5.6;int n=7;s1=f(x,n);s2=f(x 2.3,n);s3=f(x-3.2,n 3);s4=s1/(s2 s3);printf(”%f“,s4);getch(); 第七章 1:(1)D(2)A(3)D(4)B(5)D 2:(1)1 5 4 4 6 7 8 2 3 4(2)6333 3:(1)a[8]=data;k>=0 a[k]=temp break k(2)”%s“ str[i] 4、/*题目:求一组成绩的平均分数以及高于平均分的成绩。*/ #include #define max 100 void main()float a[max],s=0,average=0;int i,n;printf(”Please input N: “);/*输入要处理元素的个数*/ scanf(”%d“,&n);printf(”input %d ge shu: “,n);/*输入90,85,92,77,80,62*/ for(i=0;i scanf(”%f“,&a[i]);s =a[i];average = s / n;printf(”= %.2f“,average);/*输出81.00*/ for(i=0;i if(a[i]>average)printf(”%.2f “,a[i]);/*输出90.00,85.00,92.00*/ 5、/*题目:编写程序,输入一组整数,将他们排序后由小到大输出。*/ #include #define max 100 void main()int a[max],j,i,k=0,t=0,n=0;printf(”Please input N: “);/*输入要处理元素的个数*/ scanf(”%d“,&n);for(i=0;i scanf(”%d“,&a[i]);for(i=0;i k=i;for(j=i 1;j if(a[k]>a[j])k=j;if(k!=i)/*元素排序前下标与排序后下标不符,则交换其值*/ t=a[i];a[i]=a[k];a[k]=t;printf(”“);for(i=0;i printf(”%d “,a[i]); 6、/*题目:从键盘输入一个4x4的整数矩阵,以主对角线(┪猿浦?/ /*将左下角元素中较大者替换右上角元素,并将右上角含对称轴输出。*/ #include #include void main()int d[4][4]=0,0,0,0,i,j;clrscr();printf(”input 16 num: “);for(i=0;i for(j=0;j scanf(”%d“,&d[i][j]);for(i=0;i for(j=0;j if(d[i][j]>d[j][i])/*左下角元素大于右上角元素则交换*/ d[j][i]=d[i][j];for(i=0;i printf(”“);/*为了保持每行的间隔与每列的相同*/ for(j=0;j if(j>=i)printf(”%d“,d[i][j]);/*为了使位数不同的数输出依然保持三角型* else printf(”“); 7、*题目:输入一个3x4的二维数组,然后分别按行和按列输出。*/ #include #include void main()int d[3][4]=0,0,0,0,i,j;printf(”Please input 12 num: “);for(i=0;i for(j=0;j scanf(”%d“,&d[i][j]);printf(”hang: “);for(i=0;i for(j=0;j printf(”%d “,d[i][j]); / printf(” lie: “);for(i=0;i for(j=0;j printf(”%d “,d[j][i]); 8、/*题目:编写程序,将两个字符串连接起来,不用strcat函数。*/ #include #include void main()char s1[50],s2[50];int i=0,j=0,t=0;printf(”Input one: “);gets(s1);while(s1[i]!='')i;/*统计s1中字符个数*/ printf(”second: “);gets(s2);while(s2[j]!='')j;/*统计s2中字符个数*/ for(t=0;t s1[i]=s2[t];i;printf(” second: “);puts(s1); 9、/*输入一行字符串,统计字符对ab的个数。*/ #include #include #define MAX 100 void main()char str[MAX];int i=0,flage=0;int count=0;printf(”input a string: “);gets(str);while(str[i])if(str[i]=='a')flage=1;else if(str[i]=='b')if(flage==1)count;flage=0;else flage=0;i;printf(”the double char ab count is %d“,count); 10、#include /*相对于第一种方法,这种方法能把同为最大的字符串全部打印出来。*/#include int paixu(int a[],int n)/*构造对长度为n的数组排序的函数*/ int i,j,t,k,temp;for(i=0;i k=i;for(j=i 1;j if(a[k]>a[j])k=j;if(k!=i)t=a[i];a[i]=a[k];a[k]=t;temp=a[n-1];return temp;/*返回最大字符串的长度的值*/ void main()char str1[50],str2[50],str3[50],str4[50],str5[50],str6[50];char str7[50],str8[50],str9[50],str10[50];int count[10]=0,temp[10]=0,i,j;int paixu(int a[],int n);for(i=1;i printf(”input %d string: “,i);if(i==1)gets(str1);while(str1[count[0]])count[0];temp[0];if(i==2)gets(str2);while(str2[count[1]])count[1];temp[1];if(i==3)gets(str3);while(str3[count[2]])count[2];temp[2];if(i==4)gets(str4);while(str4[count[3]])count[3];temp[3];if(i==5)gets(str5);while(str5[count[4]])count[4];temp[4];if(i==6)gets(str6);while(str6[count[5]])count[5];temp[5];if(i==7)gets(str7);while(str7[count[6]])count[6];temp[6];if(i==8)gets(str8);while(str8[count[7]])count[7];temp[7];if(i==9)gets(str9);while(str9[count[8]])count[8];temp[8];if(i==10)gets(str10);while(str10[count[9]])count[9];temp[9];j=paixu(temp,10);for(i=1;i if(count[i-1]==j)/*只要字符串长度与最大长度相等就打印出来*/ switch(i)case 1:puts(str1);printf(”“);break;case 2:puts(str2);printf(”“);break;case 3:puts(str3);printf(”“);break;case 4:puts(str4);printf(”“);break;case 5:puts(str5);printf(”“);break;case 6:puts(str6);printf(”“);break;case 7:puts(str7);printf(”“);break;case 8:puts(str8);printf(”“);break;case 9:puts(str9);printf(”“);break;case 10:puts(str10);printf(”“);break; 11、/*给数组a输入m个按升序排列的数,给数组b输入n个按降序排列的数*/ /*将a与b中的元素按降序排列存在数组c中。*/ #include void main()int a[100],b[100],c[100],i,m,n,j,k,temp=0,s;printf(”= “);scanf(”%d“,&m);/*确定M的个数*/ printf(”= “);scanf(”%d“,&n);/*确定N的个数*/ printf(”input m ge shu: “);for(s=0;s scanf(”%d“,&a[s]);printf(”input n ge shu: “);for(s=0;s scanf(”%d“,&b[s]);i=m-1;j=0;k=0;/*i,j,分别标记a[]与b[]且都是从最大元素开始做标记*/ for(;;)if(i==0)/*a[]中只有一个数或者a[]处理到了最后一个元素*/ if(a[i] else c[k]=a[i];k;for(;;)/*把b[]数组接到c[]后面*/ c[k]=b[j];j;k;if(j==n)/*如果b[]处理完,结束。并做标记temp=1*/ temp=1;break;if(temp==1)break;/*标记temp=1,全部处理结束*/ if((a[i] c[k]=b[j];j;k;if((a[i]>b[j])&&(i!=0)&&(j!=n))c[k]=a[i];i--;k;if(j==n)/*b[]处理到完*/ for(;;)/*把b[]数组接到c[]后面*/ if(i==0) /*如果a[]处理完,结束c[k]=a[i];temp=1;break;c[k]=a[i];i--;k;if(temp==1)break;/*标记temp=1,全部处理结束*/ for(s=0;s printf(”%d ",c[s]);getch(); 并做标记temp=1*/。 C语言程序设计教程课后习题答案 第一章 C语言程序设计概述 -习题答案 算法的描述有哪些基本方法? 答 1、自然语言 2、专用工具C语言程序的基本结构是怎样的?举一个例子说明。 答 1、C语言程序由函数构成; 2、“/*”与“*/”之间的内容构成C语言程序的注释部分; 3、用预处理命令#include、#define可以包含有关文件或预定义信息; 4、大小写字母在C语言中是有区别的; 5、除main()函数和标准库函数外,用户也可以自己编写函数,应用程序一般由多个函数组成,这些函数指定实际所需要做的工作。C语言有什么特点? 答 1、具有结构语言的特点,程序之间很容易实现段的共享; 2、主要结构成分为函数,函数可以在程序中被定义完成独立的任务,独立地编译代码,以实现程序的模块化; 3、运算符丰富,包含的范围很广; 4、数据类型丰富; 5、允许直接访问物理地址,即可直接对硬件进行损伤,实现汇编语言的大部分功能; 6、限制不太严格,程序设计自由度大,这样使C语言能够减少对程序员的束缚; 7、生成的目标代码质量,程序执行效率高,同时C语言编写的程序的可移植性好。★指出合法与不合法的标识符命名。 答 AB12--√ leed_3--a*b2--× 8stu--× D.K.Jon--× EF3_3--√ PAS--√ if--× XYZ43K2--√ AVE#XY--× _762--√ #_DT5--× C.D--×说明下列Turbo C热键的功能。 答 F2:源文件存盘 F10:调用主菜单 F4:程序运行到光标所在行(用于调试程序)Ctrl+F9:编译并链接成可执行文件 Alt+F5:将窗口切换到 DOS 下,查看程序运行结果。说明下列Turbo C方式下输入并运行下列程序,记录下运行结果。 ①main() {printf(“********************n”);printf(“ welcome you n”);printf(“ very good n);printf(”********************n“);} ②main() { int a,b,c,t;printf(”please input three numbers;“);scanf(”%d,%d,%d“,&a,&b,&c);/*教材S是错误的*/ t=max(max(a,b),c);printf(”max number is:%dn“,t);} int max(int x, int y){ int z;if(x>y)z=x;else z=y;return(z);} 答 运行结果: ******************** welcome you very good ******************** 运行结果: please input three numbers;3,1,4 /*左侧下划线内容为键盘输入*/ max number is:4 7 一个C程序是由若干个函数构成的,其中有且只能有一个___函数。 答 main()8 在Turbo C环境下进行程序调试时,可以使用Run下拉菜单的___命令或按___键转到用户屏幕查看程序运行结果。 答 1、User screen 2、Alt+F5 9 ★C语言对标识符与关键字有些什么规定? 答 1、标识符用来表示函数、类型及变量的名称,它是由字母、下划线和数字组成,但必须用字母或下划线开头。 2、关键字是一种语言中规定具有特定含义的标识符,其不能作为变量或函数名来使用,用户只能根据系统的规定使用它们。C源程序输入后是如何进行保存的? 答 是以C为扩展名保存的纯文本文件。 第二章 C语言程序的基本数据类型与表达式 -习题答案 ★指出下列常数中哪些是符合C语法规定的。 答 ''--× '101'--× ”“--× e3--× 019--√ 0x1e--√ ”abn“--√ 1.e5--×(2+3)e(4-2)--× 5.2e2.5--×请找出下列程序中的错误,改正后写出程序运行结果。 ①void main(){int x,y=z=5,aver;x=7 AVER=(x+y+z)/3 printf(”AVER=%dn“,aver);} ②void main() { char c1='a';c2='b';c3='c';int a=3.5,b='A' printf(”a=%db='“endn”,a,b);printf(“a%cb%cbc%ctabcn”,c1,c2,c3);} 答 main(){int x,y=5,z=5,aver;x=7;aver=(x+y+z)/3;printf(“AVER=%dn”,aver);} 运行结果:AVER=5 ②main() { char c1='a', c2='b', c3='c';int a=3,b='A';printf(“a=%d,b='%c'”end“n”,a,b);printf(“a%cb%cbc%ctabcn”,c1,c2,c3);} 运行结果:a=3,b='A'“end” aabcc abc 3 写出下列赋值的结果,表格中写了数值的是要将它赋给其他类型的变量,将所有的空格填上赋值后的数据(实数保留到小数点后两位)。int 99 -1 char 'h' unsigned int float 55.78 long int 答 int 99 104 66 55 68-1 char 'c' 'h' 'B' '7' 'D' unsigned int 99 104 66 55 68 65535 float 99.00 104.00 66.00 55.78 68.00-1.00 long int 99 104 66 55 68-1 ★写出程序运行结果。 ①void main(){int i,j;i=8,j=10;printf(“%d,%d,%d,%dn”,i,j,++i,j++);} ②main() { int a=1,b=2,c=30;;printf(“%d,%d,%d,%dn”,a=b=c,a=b==c,a==(b=c),a==(b==c));} 注意:a=b=c,a=b==c之间应为逗号,教材有误 答 运行结果: 9,11,9,10 运行结果: 30,1,0,0 ③void main() {int a=10,b=20,c=30,d;d=++a<=10||b-->=20||c++;printf(“%d,%d,%d,%dn”,a,b,c,d);} 答 运行结果: 11,19,30,1 ★写出下面表达式的值(设a=10,b=4,c=5,d=1,x=2.5,y=3.5)。⑴a%=(b%=3) ⑵n++,a+=a-=a*=a ⑶(float)(a+c)/2+(int)x%(int)y ⑷a*=b+c ⑸++a-c+b++ ⑹++a-c+++b ⑺a ⑼a+b,18+(b=4)*3,(a/b,a%b) ⑽x+a%3*(int)(x+y)%2/4+sizeof(int)⑾a 答 ⑴0 ⑵0 ⑶9.500000 ⑷90 ⑸10 ⑹10 ⑺'A' ⑻2 ⑼4.5 ⑽1 ⑾0 ⑿20 ⒀0 下列每组表达式中,被执行后结果完全等价的是哪些(设a、b、m是已被赋值的整型变量)? ①m=(a=4,4*5)与m=a=4,4*5 ②(float)(a/b)与(float)a/b ③(int)a+b与(int)(a+b)④m%=2+a*3与m=m%2+a*3 ⑤m=1+(a=2)+(b=3)与a=2,b=3,m=1+a+b 答 ①前面是赋值表达式,而后面的是一个逗号表达式,所以一定不同; ②前面的表达式中a/b结果为一整数,结果已经取整,精度可能受到影响,之后强制float后才为浮点型,后面的是先将a转换为float后再与b相除,其值保证了精度,所以不同。 ③因为a、b均为整数,其前后两个表达式的计算结果是一致的。 ④前一表达式是一算术表达式,而后者为一赋值表达式,此为一点不同;另外,前一表达式的m只被赋过一次值,后一表达式中的m曾两次被赋值,第一次赋值时与第一表达式中的值一致,第二次赋值后即不再相同。⑤前后表达式的计算结果应该是一致的:a=2, b=3, m=6 7 条件表达式x>0?x:-x的功能是什么? 答 如果x的值是一正数,则表达式的值为x值;如果x的值是一非正数,则表达式的值为-x。其实该表达式的值即为x的绝对值,C语言中提供了一个函数fabs(x)即可完成此功能,该函数包含在math.h头文件中。用一个条件表达式描述从a、b、c中找出最大都赋给max.答 max=a>(b>c?b:c)?a:(b>c?b:c);9 ★若x为int型变量,则执行以下语句后x的值为()。x=6;x+=x-=x*x;A.36 B.-60 C.60 D.-24 答 B.10 ★若有以下类型说明语句: char w;int x;float y;double z;则表达式w*x+z-y的结果为()类型。A.float B.char C.int D.double 答 D.第三章 顺序结构程序设计 -习题答案 变量k为float类型,调用函数scanf(“%d”,&k),不能使变量k得到正确数值的原因是___。 答 格式修饰符与变量类型不一致。因为%d输入的数据类型应该为十进制整数,而&k为占用4个字节的float类型变量的地址。★a=1234,b=12,c=34,则执行“printf(“|%3d%3d%-3d|n”,a,b,c);”后的输出是___。 答 |1234 1234 | 分析如下: ①%3d为右对齐输出变量,且指定输出变量的值宽度为3个字符位,如果变量实际位数小于3,则左端补空格,如果变量实际位数大于3,则按实际长度输出,不受限制。 ②%-3d为左对齐输出变量,在输出变量时,如是变量实际位数小于3,则在右端补空格,否则按实际输出。★设有“int a=255,b=8;”,则“printf(“%x,%on”,a,b);”输出是___。答 ff,10 ①如果“printf(“%X,%on”,a,b);”则输出为FF,10。说明在输出十六进制字母时,其大小写受格式修饰符的限制,如果是“%x”则输出小写,如果是“%X”则输出大写。 ②如果希望在输出十六进制时输出前导符0x或0X,则以上输出语句应改“printf(“%#x,%on”,a,b);”为或“printf(“%#X,%on”,a,b);”。本条解释不必须掌握。★以下程序输出的结果是___。main(){ int a1=1,a2=0,a3=2;printf(“%d,%d,%dn”,a1,a1+a2+a3,a3-a1);} 答 1,3,1 5 printf函数中用到格式符%5s,其中5表示输出字符占用5列。如果字符串长度大于5,则按___输出;如果字符串长度小于5,则按___输出。 答 ①实际 ②左端补空格 6 ★已定义变量如下: int a1,a2;char c1,c2;若要求输入a1、a2、c1和c2的值,正确的输入函数调用语句是___。 答 scanf(“%d,%d,%c,%c”,&a1,&a2,&c1,&c2);7 输入两个整型变量a、b的值,输出下列算式以及运算结果___。a+b、a-b、a*b、a/b、(float)a/b、a%b 每个算式占一行。如a=10,b=5,a+b输出为:10+5=15 答 设int a=10,b=5;以下为输出语句及结果: ①printf(“%d+%d=%dn”,a,b,a+b);10+5=15 ②printf(“%d-%d=%dn”,a,b,a-b);10-5=5 ③printf(“%d*%d=%dn”,a,b,a*b);10*5=50 ④printf(“%d/%d=%dn”,a,b,a/b);10/5=2 ⑤printf(“%(float)d/%d=%fn”,a,b,(float)a/b);(float)10/5=2.000000 ⑥printf(“%d%%%d=%dn”,a,b,a%b);10%5=0 8 ★输入一个非负数,计算以这个数为半径的圆周长和面积。答 #define PI 3.1415926 main(){ float r,l,area;printf(“Input a positive:”);scanf(“%f”,&r);l=2*PI*r;area=PI*r*r;printf(“l=%ftarea=%fn”,l,area);} 9 输入任意一个3位数,将其各位数字反序输出(例如输入123,输出321)。 答 main(){ int x,y;printf(“Input a number(100-999):”);scanf(“%d”,&x);y=100*(x%10)+10*(x/10%10)+x/100;/*注意分析此处算法*/ 第二章 答案 题2.1 8086/8088通用寄存器的通用性表现在何处?8个通用寄存器各自有何专门用途?哪些寄存器可作为存储器寻址方式的指针寄存器? 答:8086/8088通用寄存器的通用性表现在: 这些寄存器除了各自规定的专门用途外,他们均可以用于传送和暂存数据,可以保存算术逻辑运算中的操作数和运算结果; 8个通用寄存器的专门用途如下: AX 字乘法,字除法,字I/O BX 存储器指针 CX 串操作或循环控制中的计数器 DX 字乘法,字除法,间接I/O SI 存储器指针(串操作中的源指针)DI 存储器指针(串操作中的目的指针)BP 存储器指针(存取堆栈的指针)SP 堆栈指针 其中BX,SI,DI,BP可作为存储器寻址方式的指针寄存器 题2.2 从程序员的角度看,8086/8088有多少个可访问的16位寄存器?有多少个可访问的8位 寄存器? 答: 从程序员的角度看,8086/8088有14个可访问的16位寄存器;有8个可访问的8位寄存器; 题2.3 寄存器AX与寄存器AH和AL的关系如何?请写出如下程序片段中每条指令执行后寄存器 AX的内容: MOV AX,1234H MOV AL,98H MOV AH,76H ADD AL,81H SUB AL,35H ADD AL,AH ADC AH,AL ADD AX,0D2H SUB AX,0FFH 答: MOV AX,1234H AX=1234H MOV AL,98H AX=1298H MOV AH,76H AX=7698H ADD AL,81H AX=7619H SUB AL,35H AX=76E4H ADD AL,AH AX=765AH ADC AH,AL AX=D15AH ADD AX,0D2H AX=D22CH SUB AX,0FFH AX=D12DH 题2.4 8086/8088标志寄存器中定义了哪些标志?这些标志可分为哪两类?如何改变这些标志的状态? 答: 8086/8088标志寄存器中定义了9个标志,如下: CF: Carry Flag ZF: Zero Flag SF: Sign Flag OF: Overflow Flag PF: Parity Flag AF: Auxiliary Carry Flag DF: Direction Flag IF: Interrupt-enable Flag TF: Trap Flag 这些标志可分为两类,分别为: 1、运算结果标志; 2、状态控制标志; 采用指令SAHF可把AH中的指定位送至标志寄存器低8位SF、ZF、AF、PF、CF; 采用CLC可清除CF,置CF到0 采用STC可置CF到1 采用CLD可置DF到0 采用sTD可置DF到1 采用CLI可置IF到0 采用STI可置IF到1 另外,在某些指令执行过程中会改变部分标志的状态; 题2.5 请说说标志CF和标志OF的差异。答: 如果把指令中处理的数据按照无符号数看待,则处理结果达到进位是,置CF为1; 如果把该处理中的数据按照有符号数看待,则处理结果超过有符号数表达范围的,置OF为1;两个标志同步进行,CPU并不知道该数的类型; 题2.6 8086/8088如何寻址1M字节的存储器物理地址空间?在划分段时必须满足的两个条件是什么?最多可把1M字节空间划分成几个段?最少可把1M字节地址空间划分成几个段? 答: 8086/8088通过对存储器分段和使用段寄存器的方式寻址1M字节的存储器物理地址空间; 在划分段时必须满足的两个条件是: 1、逻辑段的开始地址必须是16的倍数; 2、逻辑段的嘴道长度是64K; 1M的字节空间划分为64K个逻辑段;最少可把1M字节地址划分成16个逻辑段; 题2.7 在8086/8088上运行的程序某一时刻最多可访问几个段?程序最多可具有多少个段?程序至少几个段? 答: 在8086/8088上运行的程序某一时刻最多可访问4个当前段:代码段,数据段,堆栈段和附加段;程序最多可具有4种类型的段,最少要有一个代码段; 题2.8 存储单元的逻辑地址如何表示?存储单元的20位物理地址如何构成? 答: 存储单元的逻辑地址由段值和偏移两部分组成:段值:偏移; 存储单元的20位物理地址可以表示为: 物理地址=段值×16+偏移; 题2.9 当段重叠时,一个存储单元的地址可表示成多个逻辑地址。请问物理地址12345H可表示多少个不同的逻辑地址?偏移最大的逻辑地址是什么?偏移最小的逻辑地址是什么? 答: 12345H可表示1000H(4096)个不同的逻辑地址,偏移最大的逻辑地址是235:0FFF5H 偏移最小的逻辑地址是1234:0005H 题2.10 为什么称CS为代码段寄存器?为什么称SS为堆栈寄存器? 答: 因为在取指令的时候,规定的段寄存器就是CS,所以CS为代码段寄存器; 而堆栈操作时规定的寄存器是SS,所以SS为堆栈寄存器; 题2.11 请举例说明何为段前缀超越。什么场合下要使用段前缀超越? 答: 在存取一般存储器操作数时,段寄存器可以不是DS;当偏移设计BP寄存器时,段寄存器也可以不必是SS;如Mov AX,[si] 默认段地址在DS中,也可以改变:Mov AX, ES:[si] 当数据并不在默认的DS指定段时,可以采用段前缀超越; 题2.12 8086/8088的基本寻址方式可分为哪三类?他们说明了什么? 答: 8086/8088的基本寻址方式可分为以下三类: 1、存储器寻址; 2、立即寻址; 3、寄存器寻址; 他们说明了cpu有三类合计七种方式进行基本寻址; 题2.13 存储器寻址方式分为哪几种?何为存储器的有效地址? 答: 存储器寻址方式分为以下几种: 1、立即寻址; 2、直接寻址; 3、寄存器寻址; 4、寄存器间接寻址; 5、寄存器相对寻址; 6、基址加变址寻址; 7、相对基址加变址寻址; 存储器的有效地址是一个16bit的无符号数; 题2.14 什么场合下缺省的段寄存器是SS?为什么这样安排? 答: 当使用堆栈时,缺省的段寄存器是SS; 因为SS定义为堆栈段寄存器,配合SP堆栈指针,用来指向堆栈的栈顶; 题2.15 请说明如下指令中源操作数的寻址方式,并作相互比较: MOV BX,[1234H] MOV BX,1234H MOV DX,BX MOV DX,[BX] MOV DX,[BX+1234H] MOV DX,[BX+DI] MOV DX,[BX+DI+1234H] 答: MOV BX,[1234H] ;直接寻址 MOV BX,1234H :立即寻址 MOV DX,BX :寄存器寻址 MOV DX,[BX] :寄存器间接寻址 MOV DX,[BX+1234H] :寄存器相对寻址 MOV DX,[BX+DI] :基址加变址寻址 MOV DX,[BX+DI+1234H] :相对基址加变址寻址 题2.16 8086/8088提供了灵活多样的寻址方式,如何适当的选择寻址方式? 答: 每种寻址方式都有其特点,首先应该掌握不同寻址方式之间的区别,以及 适用的范围,结合程序中的需要进行灵活选择。 题2.17 设想一下这些寻址方式如何支持高级语言的多种数据结构? 答: 自己设想! 题2.18 为什么目标操作数不能采用立即寻址方式? 答: 立即寻址表示是一个操作数,并非一个存储空间,作为目标操作数是不合适的; 题2.19 处理器的通用寄存器是否越多越好?通用寄存器不够用怎么办? 答: 处理器的通用寄存器并非越多越好,因为如果处理器的通用寄存器数量太多,势必造成处理器的成本增加,同时也增加了处理器设计的复杂度; 如果通用寄存器不够用,应该采用内存中的存储单元代替,不过速度上要有所牺牲; 题2.20 哪些存储器寻址方式可能导致有效地址超出64K的范围?8086/8088如何处理这种 情况? 答: 寄存器相对寻址,基址加变址寻址,相对基址加变址寻址这三种寻址方式有可能导致有效地址超出64K的范围,8086/8088将取其64K的模进行访问; 题2.21 什么情况下根据段值和偏移确定的存储单元地址会超出1M?8086/8088如何处理这种情况? 答: 当物理地址的计算超过FFFFFH时,存储单元地址会超出1M,8086/8088将取其1M的模覆盖存取; 题2.22 8086/8088的指令集可分为哪6个子集? 答: 8086/8088的指令集可分为以下6个子集: 1、数据传输 2、算术运算 3、逻辑运算 4、串操作 5、程序控制 6、处理器控制 题2.23 8086/8088的指令集合中,最长的指令有几个字节?最短的指令有几个字节? 答: 8086/8088的指令集合中,最长的指令4个字节,最短的指令2个字节; MOV AX,[BX+SI+1234H] 题2.24 8086/8088的算术逻辑运算指令最多一次处理多少二进制位?当欲处理的数据 长度超出该范围怎么办? 答: 8086/8088的算术逻辑运算指令最多一次处理16bit的二进制位;如果处理的数据长度超出则分成若干部分进行逻辑运算,最后进行整合; 题2.25 如何时序数据段和代码段相同? 答: 将数据段的内容写入代码段中,并将代码段的段值赋给DS即可; 题2.26 通常情况下源操作数和目的操作数不能同时是存储器操作数。请给出把存储器操作 数甲送到存储器操作数乙的两种方法。答: 法一: MOV AX, [BX] MOV [SI],AX DS:[BX]=甲,DS:[SI]=乙 法二: MOV AX,[BX] XCHG AX,[SI] 法三: PUSH WORD PTR [BX] POP WORD PTR [SI] 题2.27 请用一条指令实现把BX的内容加上123并把和送到寄存器AX。答: LEA AX, [BX+123H] 题2.28 堆栈有哪些用途?请举例说明。答: 堆栈的用途主要有: 1、现场和返回地址的保护; MOV AX, OFFSET ADDRESS PUSH AX JMP XXX...RET 2、寄存器内容的保护; PUSH AX PUSH BX...POP BX POP AX 3、传递参数; PUSH [BX] CALL XXX...XXX: POP AX...4、存储局部变量; PUSH DS PUSH CS POP DS...POP DS 题2.29 在本章介绍的8086/8088指令中,哪些指令把寄存器SP作为指针使用?8086/8088指令集中,哪些指令把寄存器SP作为指针使用? 答: 以下指令把寄存器SP作为指针使用: 1、PUSH 2、POP 3、PUSHF 4、POPF 5、PUSHA 6、POPA 7、RET 8、CALL 9、RETF 题2.30 请说说标志CF的用途。请至少给出使标志CF清0的三种方法。答: CF的用途主要有: 1、配合条件转移语句进行条件转移; 2、配合移位指令实现操作数之间的位转移; 3、常作为子程序的出口参数;如DOS磁盘文件管理功能调用等; CF清0的方法: 法一: CLC 法二: ADD AX,0FFFFH 法三: CMP AX,0 题2.31 请写出如下程序片段中每条算术运算指令执行后标志CF、ZF、SF、OF、PF和AF的状态。 MOV AL,89H ADD AL,AL ADD AL,9DH CMP AL,0BCH SUB AL,AL DEC AL INC AL 答: INSTRUCTION CF ZF SF OF PF AF MOV AL,89H 0 0 0 0 0 0 ADD AL,AL 1 0 0 1 1 1 ADD AL,9DH 0 0 1 0 1 0 CMP AL,0BCH 1 0 1 0 1 0 SUB AL,AL 0 1 0 0 1 0 DEC AL 0 0 1 0 1 1 INC AL 0 1 0 0 1 1 题2.32 什么是除法溢出?如何解决16位被除数8位除数可能产生的溢出? 答: 除法溢出是指除数如果是0,或者在8位除数时商超过8位,或者在16位除时商超过16位,则认为是除法溢出,引起0中断; 首先要确定8位除数不能为0,其次要确定商的最大值不能超过8位,如果超过8位,则可 采用16位的除法; 题2.33 请写出如下程序片段中每条逻辑运算指令执行后标志ZF、SF、PF的状态: MOV AL,45H AND AL,0FH OR AL,0C3H XOR AL,AL 答: INSTRUCTION ZF SF PF MOV AL,45H 0 0 0 AND AL,0FH 0 0 1 OR AL,0C3H 0 1 0 XOR AL,AL 1 0 1 题2.34 “MOV AX,0”可寄存器AX清0。另外再写出三条可使寄存器AX清0的指令。答: 法一: XOR AX,AX 法二: AND AX,0 法三: SUB AX,AX 题2.35 请写出如下程序片段中每条移位指令执行后标志CF、ZF、SF和PF的状态。MOV AL,84H SAR AL,1 SHR AL,1 ROR AL,1 RCL AL,1 SHL AL,1 ROL AL,1 答: INSTRUCTION CF ZF SF PF MOV AL,84H 0 0 0 0 SAR AL,1 0 0 1 0 SHR AL,1 0 0 0 0 ROR AL,1 1 0 0 0(该命令不影响SF位)RCL AL,1 1 0 0 0 SHL AL,1 0 0 1 0 ROL AL,1 1 0 1 0 题2.36 8086/8088中,哪些指令把寄存器CX作为计数器使用?哪些指令把寄存器BX作为基指针寄存器使用? 答: 8086/8088中,以下指令把寄存器CX作为计数器使用: 1、LOOP 2、LOOPE 3、LOOPZ 4、LOOPNZ 5、LOOPNE 6、JCXZ 以下指令把寄存器BX作为基指针寄存器使用: 1、MOV 2、XCHG 3、LEA 4、LDS 5、LES 6、ADD...题2.37 请不用条件转移指令JG、JGE、JL和JLE等指令实现如下程序片段的功能: CMP AL,BL JGE OK XCHG AL,BL OK:......答: 如下命令可实现同样功能: PUSH CX;Reserve CX XOR CX,CX;CX=0 MOV CH,02H;CH=02H MOV CL,AL;CL=AL MOV BH,0H;BH=0 SUB CX,BX;If CH=2, AL>=BL;If CH=1, AL 题2.39 8086/8088的条件转移指令的转移范围有多大?如何实现超出范围的条件转移? 答: 8086/8088的条件转移指令的转移范围只能从-126到+129之间,如果出现超出 范围的条件转移,要借助无条件转移命令JMP; 题2.40 相对转移和绝对转移的区别是什么?相对转移的有何优点? 答: 相对转移和绝对转移的区别是相对转移记录了目标地址与当前地址的差值,而绝对转移在转移命令中直接包含了目标地址; 相对转移有利于程序的浮动,比如说增加了命令语句等; 题2.41 请指出下列指令的错误所在: MOV CX,DL XCHG [SI],3 POP CS MOV IP,AX SUB [SI],[DI] PUSH DH OR BL,DX AND AX,DS MUL 16 AND 7FFFH,AX DIV 256 ROL CX,BL MOV ES,1234H MOV CS,AX SUB DL,CF ADC AX,AL MOV AL,300 JDXZ NEXT 答: MOV CX,DL XCHG [SI],3 POP CS MOV IP,AX SUB [SI],[DI] PUSH DH OR BL,DX AND AX,DS MUL 16 AND 7FFFH,AX DIV 256 ROL CX,BL MOV ES,1234H 转 MOV CS,AX SUB DL,CF ADC AX,AL MOV AL,300 POP指令的对象不能是CS,PUSH可以 IP不能是源也不能是目的 PUSH和POP只能处理16位的操作数(8086/8088) BL不可以作为操作数 CS不能为目的 CF是Flag中的一个bit,不能如此 300超过0FFh,Over 8bit ;寄存器大小不一;不能与立即数进行交换;;;如果参与的操作数有两个,只能有一个是存储器操作数 ;;寄存器大小不一;段寄存器不可以是操作数;不可以使用立即数;立即数不能是目的操作数;不可以使用立即数;;段寄存器为目的时,源不能是立即数,需由通用寄存器;代码段寄存器;;寄存器大小不一; JDXZ NEXT ;JCXZ 题2.42 请指出如下指令哪些是错误的,并说明原因: MOV [SP],AX PUSH CS JMP BX+100H JMP CX ADD AL,[SI+DI] SUB [BP+DI-1000],AL ADD BH,[BL-3] ADD [BX],BX MOV AX,BX+DI LEA AX,[BX+DI] XCHG ES:[BP],AL XCHG [BP],ES 答: MOV [SP],AX ;SP非有效寄存器间接寻址之寄存器 PUSH CS ;对 JMP BX+100H ;对 JMP CX ;对 ADD AL,[SI+DI] ;SI和DI只能出现一个,与BX,BP一致 SUB [BP+DI-1000],AL ;对 ADD BH,[BL-3] ;BL只是一个8bit寄存器 ADD [BX],BX ;对 MOV AX,BX+DI ;对 LEA AX,[BX+DI] ;对 XCHG ES:[BP],AL ;对 XCHG [BP],ES ;段寄存器不能是操作数 题2.43 下列程序片段完成什么功能,可否有更简单的方法实现同样的功能: XCHG AX,[SI] XCHG AX,[DI] XCHG AX,[SI] 答: 程序实现[SI]和[DI]中的内容交换;AX中内容不变; 有,如下: PUSH [SI] PUSH [DI] POP [SI] POP [DI] 题2.44 请比较如下指令片段: LDS SI,[BX] MOV SI,[BX] MOV DS,[BX+2] MOV DS,[BX+2] MOV BX,[BX] 答: LDS SI,[BX] ;DS=[BX+2],SI=[BX] MOV SI,[BX];DS=[BX+2],SI=[BX] MOV DS,[BX+2] MOV DS,[BX+2];DS=[BX+2],BX=[BX] MOV BX,[BX] 第一组和第二组功能一致; 第三章答案 题3.1 伪指令语句与指令语句的本质区别是什么?伪指令的主要作用是什么? 答: 伪指令语句与指令语句的本质区别是指令语句有其对应的机器指令,而伪指令没有; 伪指令的主要作用是指示汇编程序如何汇编源程序; 题3.2 汇编语言中的表达式与高级语言中的表达式有何相同点和不同点? 答: 汇编语言中的表达式与高级语言中的表达式的相同点是都采用运算符、操作符以及括号把常数和符合连起来; 不同点是汇编语言的表达式除了数值表达式外还有地址表达式; 题3.3 汇编语言中数值表达式与地址表达式有何区别? 答: 汇编语言中数值表达式在汇编过程中由汇编程序计算出数值,而地址表达式中部分相对地址的地方,在汇编时无法确定其确定地址; 题3.4 汇编语言中的变量和标号有何异同之处? 答: 汇编语言中的变量和标号的相同之处是都代表着一个地址; 不同之处是变量表示的地址中存放的是数据,而标号表示的地址中存放的是代码; 题3.5 请计算如下各数值表达式的值: 23H AND 45H OR 67H 1234H/16+10H NOT(65535 XOR 1234H)1024 MOD 7+3 LOW 1234 OR HIGH 5678H 23H SHL 4 “Eb” GE 4562H XOR-1 1234H SHR 6 'a' AND(NOT('a'-'A')'H' OR 00100000B 76543Q LT 32768 XOR 76543 3645H AND 0FF00H 答: 23H AND 45H OR 67H;67H 1234H/16+10H;133H NOT(65535 XOR 1234H);1234H 1024 MOD 7+3;5 LOW 1234 OR HIGH 5678H;D6H 注意1234 不是1234H 23H SHL 4;30H “Eb” GE 4562H XOR-1;0 1234H SHR 6;0048H 'a' AND(NOT('a'-'A');41H or 'A' 'H' OR 00100000B;68H or 'h' 76543Q LT 32768 XOR 76543;题目最后的76543有错,按照76543Q处理:829CH 3645H AND 0FF00H;3600H 题3.6 请计算如下程序片段中各地址表达式的值,设BX=1000H,SI=2000H,DI=3000H,BP=4000H [BX+100H] [DI][BP] 2000H[SI] 10H[BX][SI] [BP-128] [BX][DI-2] 答: [BX+100H];[1100H] [DI][BP];[7000H] 2000H[SI];[4000H] 10H[BX][SI];[3010H] [BP-128];[3F80H] [BX][DI-2];[3FFEH] 题3.7 设在某个程序中有如下片段,请写出每条传送指令执行后寄存器AX的内容: ORG 100H VARW DW 1234H,5678H VARB DB 3,4 VARD DD 12345678H BUFF DB 10 DUP(?)MESS DB 'HELLO' BEGIN: MOV AX,OFFSET VARB + OFFSET MESS MOV AX,TYPE BUFF + TYPE MESS + TYPE VARD MOV AX,SIZE VARW + SIZE BUFF + SIZE MESS MOV AX,LENGTH VARW + LENGTH VARD MOV AX,LENGTH BUFF + SIZE VARW MOV AX,TYPE BEGIN MOV AX,OFFSET BEGIN 答: ORG 100H VARW DW 1234H,5678H VARB DB 3,4 VARD DD 12345678H BUFF DB 10 DUP(?)MESS DB 'HELLO' BEGIN: MOV AX,OFFSET VARB + OFFSET MESS;AX=0218H MOV AX,TYPE BUFF + TYPE MESS + TYPE VARD;AX=0006H MOV AX,SIZE VARW + SIZE BUFF + SIZE MESS;AX=000DH MOV AX,LENGTH VARW + LENGTH VARD;AX=0002H MOV AX,LENGTH BUFF + SIZE VARW;AX=000CH MOV AX,TYPE BEGIN;AX=FFFFH MOV AX,OFFSET BEGIN;AX=0119H 题3.8 设如下两条指令中的符号ABCD是变量名,请说明这两条指令的异同。 MOV AX,OFFSET ABCD LEA AX,ABCD 答: 两条指令都是将ABCD的偏移地址放入AX寄存器中; 不同之处是OFFSET只能取得用数据定义伪指令的变量的有效地址,而不能取得一般操作数的有效地址; 题3.9 请指出如下指令的不明确之处,并使其明确: MOV ES:[BP],5 ADD CS:[1000H],10H DEC SS:[BX-8] JMP CS:[SI+1000H] MUL [BX+DI+2] DIV [BP-4] 答: MOV ES:[BP],5 ;未指定存储单元属性 MOV WORD PTR ES:[BP],5 ADD CS:[1000H],10H ;同上 ADD WORD PTR CS:[1000H],10H DEC SS:[BX-8] ;同上 DEC WORD PTR SS:[BX-8] JMP CS:[SI+1000H] ;无法确定段间还是段内转移 JMP WORD PTR CS:[SI+1000H] MUL [BX+DI+2] ;无法确定是8位乘法还是16位乘法 MUL WORD PTR [BX+DI+2] DIV [BP-4] ;同上 DIV WORD PTR [BP-4] 题3.10 设在某个程序中有如下片段,请改正其中有错误的指令语句: VARW DW 1234H,5678H VARB DB 3,4 VARD DD 12345678H......MOV AX,VARB MOV VARD,BX MOV VARD+2,ES MOV CL,VARW+3 LES DI,VARW 答: MOV AX,VARB ;VARB是8bit量,应该修改AX到AL or AH MOV VARD,BX ;VARD是32bit量,要分两次传 MOV VARD+2,ES ;同上 MOV CL,VARW+3 ;同上,CL改为CX LES DI,VARW ;VARW非32位量,应改为VARD 题3.11 请举例说明伪指令ASSUME的作用。 答: ASSUME的作用是声明现在开始CS寄存器对应于哪个段,DS对应于哪个段,SS和ES分别对应哪个段,可以相同也可以不同;如: ASSUME CS:CSEG,DS:DSEG,SS:SSEG,ES:ESEG 可以根据需要重新建立对应关系; 题3.12 设在某个程序片段中有如下语句,请说明各符号的属性: SYMB1 LABEL BYTE SYMB2 EQU THIS BYTE SYMB3 DW ? SYMB4 EQU BYTE PTR SYMB3 答: SYMB1:BYTE SYMB2:BYTE SYMB3:WORD SYMB4:BYTE 题3.13 为什么说汇编语言中的等价语句EQU可理解为简单的宏定义?请举例说明。答: EQU可以用符号定义常数,表达式,指令助记符,字符串等; 而宏定义是指定一个宏指令名,宏指令可表示相对应的程序片段。 如: HELLO EQU “How are you!” 与: HELLO MACRO 'How are you!' ENDM 一致; 题3.14 设在某个程序片段中有如下语句,请说明各符号所表示的值: SYMB1 = 10 SYMB2 = SYMB1*2 SYMB1 = SYMB1 + SYMB2 + 4 SYMB3 EQU SYMB1 答: SYMB1 = 22H SYMB2 = 14H SYMB3 = 22H 题3.15 请改写3.3.3的程序T3-1.ASM,使其只有一个段。答:;程序名:T3-1.ASM;功能 :显示信息“HELLO" cseg segment assume cs:cseg mess db 'HELLO',0dh,0ah,'$' start: mov ax,cseg mov ds,ax mov dx,offset mess mov ah,9 int 21h mov ah,4ch int 21h cseg ends end start 题3.16 请说明指令”JMP $+2“指令的机器码中的地址差值是多少? 答: 2H 题3.17 源程序是否一定要以END语句结束?程序是否一定从代码段的偏移0开始执行? 如果不是,那么如何指定? 答: 源程序可以不以END语句结束,不过END之后的内容汇编程序将忽略。程序不一定要从代码的偏移0开始执行,一个比较简单的方法是利用END语句,如END XXX,程序将从XXX标号处开始执行; 题3.18 利用查表的方法实现代码转换有何特点?利用查表的方法求函数值有何特点? 答: 利用查表的方法实现代码转换的特点是: 1、转换代码间不需要直接的算术或逻辑关系,只需要安排好表的组织即可; 2、对于部分代码,其转换效率比较高,主要时间用在寻址上; 利用查表的方法求函数值的特点是: 1、对于大部分的数学函数值的求值,直接计算困难较大,采用查表法可祢补 不足; 2、程序比较简单; 3、能够得到十进制或者十六进制格式的高精度函数值。 4、函数值必须事先计算好; 5、精度无法由程序控制; 题3.19 利用地址表实现多向分支有何特点?请举例说明。答: 利用地址表实现多向分支的特点有: 1、对于实现5路以上的多向分支,使用地址表既方便又高效; 2、对于如何确定地址的位置,需要采用不同的方法实现; 例子看书。 题3.20 请举例说明如何避免条件转移超出转移范围。 答: 如果出现条件转移超出了范围,则可以利用无条件转移指令帮助跳转; 如: cmp ax,'A' jb out_program 如果超出范围: cmp ax,'A' jb out_com...out_com: jmp far ptr out_program 题3.21 请写一个程序片段统计寄存器AX中置1的个数。答: count db ?,?,0dh,0ah,'$'......call countAX cmp bl,9 ja sub10 jmp go sub10: sub bl,10 mov count,31h go: add bl,30h mov count+1,bl mov dx,offset count mov ah,9 int 21h mov ah,4ch int 21h;==============================;入口:AX;出口:BL=AX中1的个数 countAX proc mov cx,16 mov bl,0 count1: shl ax,1 jnc ADDAX1 add bl,1 ADDAX1: loop count1 ret countAX endp;============================= 题3.22 设一个32位有符号数存放在DX:AX中,请写一个求其补码的程序片段。 答: Invert proc mov bx,dx and bx,8000h cmp bx,0 jz out_1 not dx not ax add ax,1 adc dx,0 or dx,8000h out_1: nop ret Invert endp 题3.23 写一个程序片段实现如下功能:依次重复寄存器AL中的每一位,得到16位的结果存 放到DX寄存器中。 答: Expand proc mov cx,7 xor dx,dx S0: shl dx,1 shl dx,1 shl al,1 jnc CF0 add dx,3h CF0: nop loop S0 ret Expand endp 题3.24 写一个程序片段实现如下功能:依次重复四次寄存器AL中的每一位,得到32位的结果 存放到DX:AX寄存器中。 答: Expand proc mov cx,3 xor dx,dx xor bx,bx S0: shl al,1 jnc CF0 add dx,0Fh CF0: shl dx,1 shl dx,1 shl dx,1 shl dx,1 loop S0 mov cx,4 S1: shl al,1 jnc CF0_1 add bx,0Fh CF0_1: shl bx,1 shl bx,1 shl bx,1 shl bx,1 loop S1 mov ax,bx ret Expand endp 题3.25 写一个程序片段实现如下功能:把寄存器AL和BL中的位依次交叉,得到的16位结果 存放到DX寄存器中。 答: Expand proc mov cx,8 xor dx,dx S0: shl dx,1 shl al,1 jnc CF0 add dx,1h CF0: shl dx,1 shl bl,1 jnc CF0_1 add dx,1h CF0_1: loop S0 ret Expand endp 题3.26 写一个优化的程序片段,实现把字符串中的小写子母变换为对应的大写子母。设字符串 以0结尾。 答: InvertC proc begin: mov al,mess[si] cmp al,'0' jz exit_1 cmp al,61h jb next cmp al,7AH ja next and al,11011111b mov mess[si],al next: inc si jmp begin exit_1: nop ret InvertC endp 题3.27 写一个优化的程序片段,统计字符串的长度。设字符串以0结尾。答: count proc mov al,mess[si] cmp al,'0' jz exit_2 inc si jmp count exit_2: nop ret count endp;si=数量 题3.28 写一个程序片段,滤去某个字符串中的空格符号(ASCII码20H),设字符串以0结尾。 答: DeleteSpace proc;设si=0,bx=0,Mess为字符串首地址 mov al,mess[si] cmp al,'0' jz exit_2 cmp al,' ' jz next3 xchg al,mess[bx] xchg al,mess[si] inc bx next3: inc si jmp DeleteSpace exit_2: nop ret DeleteSpace endp 题3.29 请写一个把两个字符串合并的示例程序。答: dseg segment string1 db 'Welcome to $' string2 db 'Beijing!$' dseg ends cseg segment assume cs:cseg,ds:dseg start: mov ax,dseg mov ds,ax xor bx,bx xor si,si keepfind: mov al,string1[bx] cmp al,'$' jz combine inc bx jmp keepfind combine: mov al,string2[si] mov string1[bx],al cmp al,'$' jz exit inc si inc bx jmp combine exit: mov dx,offset string1 mov ah,09h int 21h mov ah,4ch int 21h cseg ends end start 题3.30 请写一个可把某个字变量的值传唤为对应二进制数ASCII码串的示例程序。答:;Name : Show_hex_ascii;input : ah=Hex;output: dx='Hex' show_hex_ascii proc mov dh,ah and dh,0f0h;reserve high 4bit shr dh,4 add dh,30h;change 0-9 to '0-9' cmp dh,39h ja add_dh_7 dh_ok: mov dl,ah and dl,0fh;reserve low 4bit add dl,30h cmp dl,39h ja add_dl_7 dl_ok: nop ret add_dl_7: add dl,7h;revert A-F to 'A-F' jmp dl_ok add_dh_7: add dh,7h jmp dh_ok show_hex_ascii endp 题3.31 请写一个可把某个十进制数ASCII码串转换成对应非压缩BCD何压缩BCD的示例程序。 答:;非压缩BCD码 ;Input ah=十进制数ASCII码 ;Output al=非压缩BCD码 TEST1 proc cmp ah,'0' jb exit cmp ah,'9' ja exit sub ah,30h mov al,ah exit: nop ret TEST1 endp ;压缩BCD码 ;Input ax=两个十进制数ASCII码 ;Output bl=压缩BCD码 TEST2 proc cmp ah,'0' jb exit cmp ah,'9' ja exit sub ah,30h mov bl,ah shl bl,4 cmp al,'0' jb exit cmp al,'9' ja exit1 sub al,30h add bl,al exit1: nop ret TEST2 endp 题3.32 请写一个可把某个十进制数ASCII码转换为对应的二进制的示例程序。答: table db '0000','0001','0010','0011','0100','0101','0110','0111' db '1000','1001'......;Input bl=一个十进制数ASCII码 ;Output dx:ax=二进制ASCII码 ;程序未检验该十进制数是否在范围以内 TEST3 proc sub bl,30h xor bh,bh shl bx,1 shl bx,1 mov dh,table[bx] mov dl,table[bx+1] mov ah,table[bx+2] mov al,table[bx+3] ret TEST3 endp 题3.33 请写出一个可把某个十六进制数ASCII码转换为对应的二进制的示例程序。答: table db '0000','0001','0010','0011','0100','0101','0110','0111' db '1000','1001','1010','1011','1100','1101','1110','1111'......;Input bl=一个十六进制数ASCII码 ;Output dx:ax=二进制ASCII码 TEST3 proc cmp bl,30h jb exit1;小于30H的不在范围内 sub bl,30h cmp bl,0Ah;如果在9以内,开始转换0-9 jb change1 sub bl,0Ah cmp bl,6h;如果在‘9’-‘A’之间,不在范围内 jb exit1 sub bl,6h;‘A’=0 cmp bl,7h;如果在‘A’-‘F’之间,开始转换 jb change2 cmp bl,21h;如果大于‘F’,看是否在‘F’和‘a’之间 jb exit1;如果在,则不在范围内 sub bl,20h;'a'=0 cmp bl,6h;如果大于‘f’,则不在范围内 ja exit1 change2: add bl,9h;按照table表,如果A=0还需要加9才可以 change1: xor bh,bh shl bx,1 shl bx,1 mov dh,table[bx] mov dl,table[bx+1] mov ah,table[bx+2] mov al,table[bx+3] exit1: ret TEST3 endp 题3.34 请写一个实现数据块移动的示例程序。答: data segment data1 db 'Hello!!.....$'....data2 db 128 dup(?)data ends ....xor ax,ax xor bx,bx mov1: mov al,data1[bx] cmp al,'$' jz out1 mov data2[bx],al inc bx jmp mov1 out1:......题3.35 请编一个程序求从地址F000:0000H开始的64K字节内存区域的检验和,并转换为 十六进制的数的ASCII码串。 答:;F000:0000H 字检验和 ;Output: BX=字检验和 TEST5 proc mov ax,0F000H mov es,ax mov cx,0ffffh xor si,si xor bx,bx ADD0: add bx,es:[si] inc si inc si loop add0 ret TEST5 endp table1 db '0','1','2','3','4','5','6','7','8','9' db 'A','B','C','D','E','F';Input bx=字检验和 ;Output dx:ax=字检验和ASCII码 TEST4 proc push cx mov cx,bx push cx mov cl,12 shr bx,cl pop cx mov dh,table1[bx] mov bx,cx and bx,0F00h push cx mov cl,8 shr bx,cl pop cx mov dl,table1[bx] mov bx,cx and bx,00f0h push cx mov cl,4 shr bx,cl pop cx mov ah,table1[bx] mov bx,cx and bx,000fh mov al,table1[bx] mov bx,cx pop cx ret TEST4 endp 题3.36 设已在地址F000:0000H开始的内存区域安排了100个字节的无符号8位二进制数。 请编写一个程序求它们的和,并转换为对应十进制数的ASCII码串。 答:;从 F000:0000H开始100个byte无符号数相加 ;output BX=Sum TEST6 proc push cx push ax push si mov ax,0f000h mov es,ax xor bx,bx xor si,si xor ax,ax mov cx,100 ADD2: mov al,es:[si] add bx,ax inc si loop ADD2 pop si pop ax pop cx ret TEST6 endp ......Dec_ASC db ' $';在数据区 ......;Name:Convert1;function: Hex convert to Dec;Input: BX=a word of Hex;Output: DS:Dec_ASC Convert1 proc push ax push cx push dx mov ax,bx xor dx,dx mov cx,2710h;2710H=10000 div cx add ax,30h mov dec_asc[0],al;[0]=万位 mov ax,dx xor dx,dx mov cx,3E8h;3E8H=1000 div cx add ax,30h mov dec_asc[1],al;[1]=千位 mov ax,dx mov cl,64h;64H=100 div cl add al,30h mov dec_asc[2],al;[2]=百位 mov al,ah mov ah,0 mov cl,0ah;0A=10 div cl add ax,3030h mov dec_asc[3],al;[3]=十位 mov dec_asc[4],ah;[4]=个位 pop dx pop cx pop ax ret Convert1 endp 题3.37 设已在地址F000:0000H开始的内存区域安排了1024个16位有符号数。请编写一个程序 统计其中的正数、负数和零的个数,并分别转换为对应的十进制数的ASCII码串。 答:;从 F000:0000H开始1024个Word有符号数统计 ;output Di=0的个数 ;Bx=正数的个数 ;DX=负数的个数 TEST7 proc push cx push ax push si mov ax,0f000h mov es,ax xor bx,bx xor si,si xor ax,ax xor di,di xor dx,dx mov cx,1024 Next1: mov ax,es:[si] cmp ax,0 jnz check_P inc di jmp next2 check_p: shl ax,1 jnc ADD_P inc dx jmp next2 ADD_P: inc bx next2: inc si inc si loop Next1 pop si pop ax pop cx ret TEST7 endp 分别call convert1, 并保存到不同的地方即可; 题3.38 设从地址F000:0000H开始的内存区域是缓冲区,存放了一组单字节的正数或负数,以0结尾。请编写一个程序确定其中最大的正数和最小的负数。 答:;从 F000:0000H开始以0结尾的单字节正数负数统计 ;output bh=最大的正数 ;bl=最小的负数 TEST8 proc xor bx,bx xor si,si mov ax,0F000h mov es,ax next9: mov al,es:[si] cmp al,0 jz exit9 test al,80h jnz Neg_1 cmp al,bh jb next7 xchg al,bh next7: inc si jmp next9 Neg_1: cmp al,bl jg next8 xchg al,bl next8: inc si jmp next9 exit9: ret TEST8 endp 题3.39 设从地址F000:0000H开始的1K字节内存区域是缓冲区。请写一个可收集该区域内 所有子串“OK”开始地址的程序 答:;从 F000:0000H开始1K字节内存区域,统计子串“OK”开始地址 ;output 开始地址=ADDRESS TEST9 proc xor bx,bx xor si,si mov ax,0F000h mov es,ax mov cx,1024 next5: mov ax,es:[si] cmp ax,'OK' jnz next6 mov ADDRESS[BX],si inc bx inc bx next6: inc si inc si loop next5 ret TEST8 endp 题3.40 请优化3.6.2节例7所示排序程序。答:自己优化下; 《C语言程序设计教程》 课后习题参考答案 习题1 1.(1)编译、链接 .exe(2)函数 主函数(或main函数)(3)编辑 编译 链接 2.(1)-(5):DDBBC(6)-(10):ABBBC 3.(1)答:C语言简洁、紧凑,使用方便、灵活;C语言是高级语言,同时具备了低级语言的特征;C语言是结构化程序设计语言,具有结构化的程序控制语句;C语言有各种各样的数据类型;C语言可移植性好;生成目标代码质量高,程序执行效率高。 (2)编辑、编译、链接、执行 (3)一个C程序由一或多个函数组成,一函数若干条语句构成,每条语句的末尾必须以分号结束。 (4)标识符,关键字,运算符,分隔符,常量,注释符等 4.从键盘输入一个双精度小数,打印出它的余弦值。#include 第2章 1.(1)BDE、ACFG(2)D(3)C(4)C 2.(1)错(2)错(3)错(4)对(5)错 3.(1)a=3,b=-27(2)a=11,b=6,c=6(3)3(4)1 0 1 0 1 1 0(5)-9 9 8(6)1)20 2)8 3)70 4)0 5)0 6)0 4.(1) #include *n”);printf(“ ***n”);printf(“ *****n”);printf(“*******n”);}(4)#include 第4章 1.(1)-(5):CAACA 2.(1)BBB(2)AAABBBCCC(3)end(4)d=20(5)s=2,t=3(6)first third(7)y=0 y=5 y=10 y=5 3.(1)y ch>=‟a‟&&ch<=‟z‟ ch = ch-32(3)x>2&&x<=10 x>-1&&x<=2(4)t=x;x=y;y=t;4.(1)#include if(x>y){ t=x;x=y;y=t;} if(x > z){ t = x;x = z;z= t;} if(y > z){ t = y;y= z;z = t;} printf(“%d %d %dn”, x, y ,z);}(2)#include if(score < 0 || score > 100) printf(“成绩不合理n”); else if(score>=90) printf(“优秀n”); else if(score>=80) printf(“良好n”); else if(score >= 70) printf(“中等n”); else if(score >= 60) printf(“及格n”); else printf(“不及格n”);}(3)#include scanf(“%d”, &n); g = n%10;//个位 s = n/10%10;//十位 b = n/100%10;//百位 q = n/1000%10;//千位 if(n < 10)//一位数 { printf(“%dn”, 1);//位数 printf(“%dn”, g);//各位上的数值 } else if(n < 100)//两位数 { printf(“%dn”, 2);//位数 printf(“%d %dn”, g,s);} else if(n < 1000)//三位数 { printf(“%dn”, 3);//位数 printf(“%d %d %dn”, g, s, b); } else if(n < 10000)//四位数 { printf(“%dn”, 4);//位数 printf(“%d %d %d %dn”, g, s, b, q); } }(4)#include if(n % 3==0 && n%5==0 && n%7==0) printf(“能同时被3、5、7整除n”); else if(n%3==0 && n%5==0) printf(“能被3和5整除n”); else if(n%3==0 && n%7==0) printf(“能被3和7整除n”); else if(n%5==0 && n%7==0) printf(“能被5和7整除n”); else if(n%3==0 || n%5==0 || n%7==0){ if(n%3==0) printf(“能被3整除n”); else if(n%5==0) printf(“能被5整除n”); else printf(“能被7整除n”); } else printf(“不能被3、5、7中任一个数整除n”);}(5)#include carType;//车型。1代表夏利;2代表富康;3代表桑塔纳 double xiali = 2.1;//每公里价格 double fukang = 2.4;double sangtana = 2.7;double distance;//距离 double totalMoney;//总的收费 printf(“请输入您乘坐的车型:1代表夏利;2代表富康;3代表桑塔纳:”);scanf(“%d”, &carType);printf(“请输入您乘车的总路程:”);scanf(“%lf”, &distance);if(carType == 1)//夏利 { if(distance < 3) totalMoney = 7.0; else totalMoney = 7 + xiali *(distance – 3);} else if(carType == 2)//富康 { if(distance < 3) totalMoney = 8.0; else totalMoney = 8 + fukang *(distance – 3);} else if(carType == 3)//富康 { if(distance < 3) totalMoney = 9.0; else totalMoney = 9 + sangtana *(distance – 3);} printf(“(四舍五入)您的车费为:%.0lfn”, totalMoney);}(6)#include if(a+b>c && b+c>a && c+a>b){ if(a==b && b==c) printf(“等边三角形n”); else if(a==b || b== c || c==a) printf(“等腰三角形n”); else printf(“一般三角形n”); } else printf(“不能构成三角形n”);} 第5章 1.(1)C(2)C(3)K=36(4)C(5)B 2.(1)3次 (2)x>=1 && x<=10 || x>=200&&x<210(3)e == 0(4)6次(5)10 3.(1)20,10(2)16,0(3)7BAB4BAB1BC(4)ABABABC(5)****** ****** ****** ****** 4.(1)a!= b (2)n / 10(3)scanf(“%d”, &a); 5.(3)行 int fac = 1, sum = 0;6.(1)#include { if(ch>=‟A‟&&ch<=‟Z‟ || ch>=‟a‟&&ch<=‟z‟) alpha++; else if(ch>=‟0‟ && ch<=‟9‟) digit++; else if(„ „ == ch) space++; else other++;} printf(“%d %d %d %dn”, alpha, digit, space, other);}(2)#include for(m10 = 1;m10<10;m10++) if(20*m20+10*m10 == 100) printf(“%d, %dn”, m20, m10);} }(3)#include for(y=0;y<10;y++) for(z=0;z<10;z++) if(x*100+y*10+z + y*100+z*10+z == 532) printf(“%d %d %dn”, x, y, z);}(4)#include for(row = 1;row <= n;++row){ for(spaceCount = 1;spaceCount <= n1;++starCount) printf(“*”);//打印出某行上的所有星号 printf(“n”);//换行 } //打印下半部分 for(row=1;row for(spaceCount = 1;spaceCount <= row;++ spaceCount) printf(“ ”);//打印出某行上星号前的空格 for(starCount = 1;starCount <= 2*(n-row)byear;if(nmonth age--;else if(nmonth == bmonth && nday>bday) age--;return age;} (4) #include int sum(int n){ int s=0;while(n){ s += n % 10; n /= 10;} return s;} (5) #include int i;for(i=1;i<=n;i++){ f *= i; s += f;} return f;} (6) #include r = m % n;while(r){ m = n; n = r; r = m % n;} return n;} (7) #include r = m % n;while(r){ m = n; n = r; r = m % n;} return n;} int lcm(int m, int n){ return m*n/gcd(m,n);} (8) #include int y;scanf(“%lf%d”, &x, &y);printf(“%lfn”, mypower(x,y));} double mypower(double x, int y){ int i;double f=1.0;for(i=1;i<=y;i++) f *= x;return f;} 第7章 1.(1)6(2)5(3)不能 (4)int a[3][2]={{1,2}, {3,4}, {5,6} };(5)6 9(6)abc G 2.(1) #include void reverse(int a[ ], int n); int main() { int array[10]={0}; int i; printf(“请输入10个整数:”); for(i=0;i<10;i++) scanf(“%d”, &array[i]); reverse(array, 10);//调用函数逆序存储数组中的数据 printf(“逆序后的元素为:n”); for(i=0;i<10;i++) printf(“%5d”, array[i]); printf(“n”); return 0; } void reverse(int a[ ], int n) { int i; int tmp; for(i=0;i { tmp = a[i];a[i] = a[n-i-1]; } } (2) #include void reverseStr(char str[ ]){ int i,j;char t;i=0;j=strlen(str)-1;while(i < j){ t = str[i]; a[n-i-1] = tmp; str[i] = str[j]; str[j] = t; i++; j--;} } (3) #include scanf(“%d”, &s1[i]);count = copyTo(s1, 10, s2);for(i=0;i printf(“%d ”, s2[i]);printf(“n”);} int copyTo(int s1[], int n, int s2[ ]){ int i, j=0;for(i=0;i if(s1[i] % 2) s2[j++] = s1[i];} return j;} (4) #include if(str1[i]>='a'&&str1[i]<='z') { str2[j] = str1[i]; j++; } i++;} str2[j] = ' ';return j;} (5) #include j = 0;while(str[i]){ if(str[i]!= ch) { str[j++] = str[i]; } i++; } str[j] = ' ';} (6) #include if(str[i] == ch1) str[i] = ch2; i++;} } (7) #include int transformToBin(int dnum, int bin[ ]); int main() { int array[32]={0};//保存转换后的二进制数 int num;//待转换的整数 int cc;//最后得到的二进制总共多少位 printf(“请输入一个整数:”); scanf(“%d”, &num); cc = transformToBin(num, array);//调用转换函数 cc--;//往回退一个元素下标,使cc指向最后一个元素 for(;cc>=0;cc--)//输出转换后的二进制数 printf(“%d”, array[cc]); printf(“n”); return 0; } int transformToBin(int dnum, int bin[ ]){ int count = 0;while(dnum)//当dnum还未转换完毕 { bin[count++] = dnum % 2;//余数保留到数组对应元素中 dnum /= 2;//数本身除2 } return count;} (8) #include int num;//待转换的整数 int cc;//最后得到的进制总共多少位 printf(“请输入一个整数:”);scanf(“%d”, &num);cc = transformToHex(num, array);//调用转换函数 cc--;//往回退一个元素下标,使cc指向最后一个元素 for(;cc>=0;cc--)//输出转换后的进制数 printf(“%c”, array[cc]);printf(“n”);return 0;} int transformToHex(int dnum, char hex[ ]){ int count = 0;int t;while(dnum)//当dnum还未转换完毕 { t = dnum % 16; if(t < 10) hex[count] = t+'0';//余数保留到数组对应元素中 else hex[count] = t-10+'A'; count++;dnum /= 16;//数本身除16 } return count;}(9) #include #define M 5 //行 #define N 6 //列 void generate(int a[ ][N], int row, int col);void display(int a[][N], int row, int col);void getMaxEveryRow(int a[][N], int row, int col, int y[]);main(){ int arr[M][N], y[M]={0};int i;generate(arr, M, N);display(arr, M, N);getMaxEveryRow(arr,M,N,y);//输出最大值 for(i=0;i printf(“%d ”, y[i]);printf(“n”);} void generate(int a[ ][N], int row, int col){ int i,j;srand(time(NULL));for(i=0;i for(j=0;j a[i][j] = rand()%101;} void display(int a[][N], int row, int col){ int i,j;for(i=0;i for(j=0;j printf(“%4d”, a[i][j]); printf(“n”);} } void getMaxEveryRow(int a[][N], int row, int col,int y[]){ int i,j;for(i=0;i y[i] = a[i][0]; for(j=1;j if(y[i] < a[i][j]) y[i] = a[i][j];} } (10) #include #define M 5 //行 #define N 6 //列 void generate(int a[ ][N], int row, int col);void display(int a[][N], int row, int col);void getMinEveryCol(int a[][N], int row, int col);main(){ int arr[M][N];int i;generate(arr, M, N);display(arr, M, N);getMinEveryCol(arr,M,N);//输出最小值 for(i=0;i printf(“%d ”, arr[0][i]);printf(“n”);} void generate(int a[ ][N], int row, int col){ int i,j;srand(time(NULL));for(i=1;i for(j=0;j a[i][j] = rand()%101;} void display(int a[][N], int row, int col){ int i,j;for(i=1;i for(j=0;j printf(“%4d”, a[i][j]); printf(“n”);} } void getMinEveryCol(int a[][N], int row, int col){ int i,j;for(i=0;i a[0][i] = a[1][i]; for(j=2;j if(a[0][i] > a[j][i]) a[0][i] = a[j][i];} } 第8章 1.(1)局部 (2)void(3)auto(4)auto(5)return(6)递归 (7)求 1!+2!+3!+4!+5!(8)注意全局变量和局部变量的区别 2.(1) #include c = xc(a, b);printf(“ %lfn”, c);} double xc(double x, double y){ return sqrt(x*x+y*y);} (2) static extern register #include s = second+minute*60+hour*60*60;} else { s = 60-second+(60-minute-1)*60+(12-hour-1)*60*60;} return s;} (3) #include printf(“%dn”, n);} int fun(int n){ int i;for(i=2;i if(n%i == 0) break;if(i return 0;else return 1;} (4) #include if(fun(n)) { printf(“%4d”, n); count++; if(count % 10 == 0) printf(“n”); } printf(“n”);} int fun(int n){ int i;for(i=2;i if(n%i == 0) break;if(i return 0;else return 1;} (5) #include return 3;return 2*func(n-1)-1;} (6) #include t=x;x=y;y=t;} printf(“%dn”, gcd(x,y));} int gcd(int m, int n){ if(0==n) return m;return gcd(n, m%n);} 第9章 1.(1)xyzNKT(2)bcdefgh(3)4,4(4)qponmzyx(5)abcCD(6)0 2.(1) #include reverse(a,10);for(i=0;i<10;i++) printf(“%d ”, a[i]);printf(“n”);} void reverse(int *p, int n){ int *q;int t;q = p + n1;while(str < pEnd){ t = *str; *str = *pEnd; *pEnd = t; str++; pEnd--;} }(3) #include printf(“%d ”, b[i]);printf(“n”);} int copyTo(int *s1, int n, int *s2){ int count=0;int *ps1, *ps2;ps2 = s2;for(ps1 = s1;ps1 < s1 + n;ps1++){ if(*ps1 % 2)//奇数 { *ps2++ = *ps1; } } return ps2-s2;} (4) #include if(*str1 >= 'a' && *str1 <= 'z') { *str2++=*str1; } str1++;} *str2 = ' ';} (5) #include if(*str!= ch) *p++ = *str; str++;} *p = ' ';} (6) #include printf(“输入替换字符:”);c2 = getchar();replaceAll(s,c1, c2);puts(s);} void replaceAll(char *str, char ch1, char ch2){ while(*str){ if(*str == ch1) { *str = ch2; } str++;} } (7) #include int num;//待转换的整数 int cc;//最后得到的进制总共多少位 printf(“请输入一个整数:”);scanf(“%d”, &num);cc=transformToBin(num, array);//调用转换函数 cc--;//使cc指向最后一个元素 for(;cc>=0;cc--)//输出转换后的进制数 printf(“%d”, array[cc]);printf(“n”);return 0;} int transformToBin(int dnum, int *bin){ int *pb;int t;pb = bin;while(dnum)//当dnum还未转换完毕 { t = dnum % 2; *pb = t; pb++; dnum /= 2;//数本身除2 } return pb-bin;} (8) #include int num;//待转换的整数 int cc;//最后得到的进制总共多少位 printf(“请输入一个整数:”);scanf(“%d”, &num);transformToHex(num, array);//调用转换函数 cc=strlen(array)-1;//使cc指向最后一个元素 for(;cc>=0;cc--)//输出转换后的进制数 printf(“%c”, array[cc]);printf(“n”);return 0;} void transformToHex(int dnum, char *hex){ char *ph;int t;ph = hex;while(dnum)//当dnum还未转换完毕 { t = dnum % 16; if(t < 10) *ph = t+'0'; else *ph = t-10+'A'; ph++;dnum /= 16;//数本身除16 } *ph = ' ';} (9) #include if(*str>='A'&&*str<='Z') *str = *str + 32; str++;} } 第10章 1.(1)12(2)(++p)->num(5)B(6)B 2.(1) struct myDate{ int year, month, day;}; (2) struct empInfo{ char empNo[15];char empName[10];char xb;//性别 int age;struct myDate empDay;double salary;}; (3) #include 3)D 7)10,A 4)p2!= NULL (((int score;}STUD;main(){ STUD a;printf(“姓名:”); gets(a.name);printf(“身高:”); scanf(“%f”, &a.height); printf(“成绩:”); scanf(“%d”, &a.score); //输出信息(仅为测试用) printf(“%s %.2f %d n”, a.name, a.height, a.score);} 第11章 1.(1)打开文件:fopen 关闭文件:fclose 使用: FILE *fp; fp = fopen(“myfile”, “r”); … fclose(fp); (2)”w” (3)文本文件:内容均以字符的形式存储,占的字节数可能会大些 二进制文件:内容以二进制编码的形式存储,占的字节数可能会稍小。 (4)第一个参数:读取得到的信息存储在内存的哪个地方 第二个参数:读取的字节数 第三个参数:读取的块数 第四个参数:文件指针,表示从哪个文件中读取数据 (5)第一个参数:待写入文件的信息存储在内存的哪个地方 第二个参数:写入的字节数 第三个参数:写入的块数 第四个参数:文件指针,表示要写入到哪个文件中(6)为了安全,gets少用,因为其没有指定输入字符的大小,限制输入缓冲区得大小,如果输入的字符大于定义的数组长度,会发生内存越界,堆栈溢出。后果非常怕怕fgets会指定大小,如果超出数组大小,会自动根据定义数组的长度截断。 2.(1) #include fpr = fopen(“a.txt”, “r”);fpw = fopen(“b.txt”, “a”); if(NULL==fpr){ printf(“文件打开不成功n”); return 0;} if(NULL == fpw){ printf(“文件打开不成功n”); return 0;} while(!feof(fpr)){ ch = fgetc(fpr); fprintf(fpw, “%c”, ch);} fclose(fpr);fclose(fpw);} (2) #include fp2 = fopen(“b.txt”, “wb”);//以二进制的形式写入 if(NULL==fp1){ printf(“文件打开不成功n”); return 0;} if(NULL == fp2){ printf(“文件打开不成功n”); return 0;} fprintf(fp1, “%lf”, pi);fwrite(&pi,sizeof(pi),1,fp2); fclose(fp1);fclose(fp2);} 打开之后的效果: (3) #include if(NULL==fpr){ printf(“文件打开不成功n”); return 0;} while(!feof(fpr)){ putchar(fgetc(fpr));} fclose(fpr);} (4) #include for(i=0;i printf(“请输入第%d个学生信息:n” , i+1); printf(“ 学号:”); gets(s[i].no); printf(“ 姓名:”); gets(s[i].name); printf(“ 成绩:”); scanf(“%d”, &s[i].score); fflush(stdin);//清除键盘缓冲区 } //打开文件,并写入 fp = fopen(“a.txt”, “wb”);if(NULL == fp){ printf(“文件打开不成功,不能写入n”); return 0;} for(i=0;i fwrite(&s[i], sizeof(s[i]), 1, fp);fclose(fp); //以下代码从文件中读取出信息,并显示在屏幕上 fp = fopen(“a.txt”, “rb”); } count = 0;while(!feof(fp)){ if(fread(&s[count], sizeof(s[count]), 1, fp)) count++;} fclose(fp);//输出 for(i=0;i第二篇:C语言程序设计教程_杨路明__课后习题答案
第三篇:C语言程序设计教程课后习题答案
第四篇:80X86语言程序设计教程(杨季文)课后习题答案
第五篇:C语言程序设计教程 课后习题参考答案