C程序设计第三版习题参考解答(全)

更新时间:2023-10-02 22:39:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

C程序设计(第三版)课后习题参考解答

第1章 C语言概述

1.5 参照本章例题,编写一个C程序,输出以下信息: ******************************

Very Good!

****************************** 解: main ( )

{printf(“****************************** \\n”); printf(“\\n”);

printf(“ Very Good! \\n”);

printf(“\\n”);

printf(“****************************** \\n”); }

1.6 写一个程序,输入a,b,c三个值,输出其中最大者。 解: main ( )

{int a,b,c,max;

printf(“请输入三个数a,b,c: \\n”); scanf(“%d,%d,%d”,&a,&b,&c); max=a;

if (max

max=c;

printf(“ 最大数为:%d ”,max); }

第2章 程序的灵魂——算法

2.1 什么叫结构化的算法?为什么要提倡结构化的算法?

解:由一些基本结构顺序组成的算法称为结构化的算法。由于在基本结构之间不存在非顺序的跳转,流程的转移只存在于一个基本结构范围之内,因而提高了算法的质量。

2.7 什么叫结构化程序设计?它的主要内容是什么?

解:结构化程序就是用高级语言表示的结构化算法。它的主要内容包括“自顶向下,逐步细化”的分析方法和“模块化设计”的解决方法,以及“结构化编码”的实现方法。

第3章 数据类型、运算符与表达式

3.3请将下面各数用八进制和十六进制数表示:

(1)10 (2)32 (3)75 (4)-617 (5)-111 (6)2483 (7)-28654 (8)21003 解:(1) (10) 10=(12) 8=(A) 16

(2) (32)10=(40)8=(20) 16 (3) (75)10=(113)8=(4B) 16

(4) (-617)10=(176627)8=(FD97) 16

此题可以这样考虑:带符号数在计算机中采用补码表示,正数的补码与原码相同,负数的补码=模+真值。若使用16位存储,模为216=65536。-617的补码为65536+(-167)=64919=(176627)8=(FD97)16 (5) (-111)10=(177621)8=(FF91) 16 (6) (2483)10=(4663)8=(9B3) 16

(7) (-28654)10=(110022)8=(9012) 16 (8) (21003)10=(51013)8=(520B) 16

3.4将以下三各整数分别赋给不同类型的变量,请画出赋值后数据在内存中的存储形式。 变量的类型 int型 long型 25 -2 32769 sort型 signed char(8位) unsigned int型 unsigned long型 unsigned short型 unsigned char型 注:如果没有学过二进制和补码,此题可以不做。

解:各数据在内存中的存储形式如下表所示: 变量的类型 int型 long型 short型 signed char(8位) unsigned int型 unsigned long型 unsigned short型 unsigned char型 25 00? 000011001 8 位 -2 1111111111111110 15 11 ? 1110 31 1111111111111110 15 11111110 11 ? 110 15 11 ? 110 31 11 ? 110 15 32769 100 ? 001(溢出) 14 00? 0100 ? 001 16 14 100 ? 001(溢出) 14 00000001(溢出) 100 ? 001 14 00? 0100 ? 001 16 14 100 ? 001 8 00? 000011001 24 100? 000011001 8 100011001 00? 000011001 8 00? 000011001 24 00? 000011001 8 00011001 11111110 00000001 其中int和short类型,其取值范围是-32768~32767。32769在这两种类型中实际表示负数,它是一个负数的补码,对其再求一次补码可得其真值,即-(65536-32769)=-32767。 char和unsigned char为8位,若将int或long类型数据赋给这种类型,则截取数据低8位。同理,若将long赋给int,则截取低16位。 3.5字符常量和字符串常量有什么区别?

解:字符常量是一个字符,用单引号括起来。字符串常量是由0个或若干个字符组合而成,用双引号括起来,存储时自动在字符串最后加一个结束符号?\\0?。

3.6写出以下程序运行的结果:

main ( )

{ char cl=?a?, c2=?b?, c3=?c?, c4=?\\101?, c5=?\\116?; printf (“a%c b%c\\t c%c\\t abc\\n”, c1, c2, c3); printf (“\\t\\b%c %c”, c4, c5); }

解:程序运行的结果为: aabb

cc

abc

AN

3.7要将“China”译成密码,密码规律是:用原来的字母后面第4个字母代替原来的字母。例如,字母“A”后面第4个字母是“E”,用“E”代替“A”。因此,“China”应译为“Glmre”。请编一程序,用赋初值的方法使c1,c2,c3,c4,c5这5个变量的值分别为’C’,’h’,’i’,’n’,’a’,经过运算,使c1,c2,c3,c4,c5的值分别变为’G’,’l’,’m’,’r’,’e’,并输出。 解: main ( )

{ char cl=?C?, c2=?h?, c3=?i?, c4=?n?, c5=?a?; c1+=4; c2+=4; c3+=4; c4+=4;

c5+=4;

printf(“密码是%c%c%c%c%c\\n, c1, c2, c3, c4, c5); }

运行结果:

密码是Glmre

3.8例2.6能否改成如下:

main ( )

{ int c1, c2; (原为 char c1, c2) c1=97;

c2=98;

printf (“%c %c\\n”, c1, c2);

printf (“%d %d\\n”, c1, c2); }

解:可以。因为在可输出的字符范围内,用整型和用字符型作用相同。

3.9求下面算术表达式的值。 (1) x+a%3*(int)(x+y)%2/4

设x=2.5,a=7,y=4..7 (2) (float)(a+b)/2+(int)x%(int)y

设a=2,b=3,x=3.5,y=2.5

解: (1)2.5 (2)3.5

3.10写出程序运行的结果。 main ( )

{ int i, j, m, n; i=8; j=10; m=++i; n=j++;

printf (“%d, %d, %d, %d”, i, j, m, n); }

解:运行结果为: 9,11,9,10

3.11写出下面赋值的结果。格中写了数值的是要将它赋给其他类型的变量,将所有空格填上赋值后的数值。 int char unsigned int float long int 解: int char unsigned int float long int

3.12 出下面表达式运算后a的值,设原来a=12。设a和n都已定义为整型变量。 (1)a+=a (2)a-=2 (3)a*=2+3 (4)a/=a+a (5)a%=(n%=2),n的值等于5 (6)a+=a-=a*=a

99 99 ?c? 99 99.000000 99 ?d? 100 ?d? 100 100.000000 100 76 76 ?L? 76 76.000000 76 53.65 53 ?5? 53 53.65 53 68 68 ?D? 68 42 42 ?*? 42 ⅹ 65535 -1 ⅹ 65535 68.000000 42.000000 65535.000000 68 42 65535

运行结果:

请输入利润i:234000↙ 奖金是:19200.00

5.9输入4个整数,要求按由小到大的顺序输出。 解:程序如下 #include \void main() {

int t,a,b,c,d;

printf(\请输入4个整数:\ scanf(\ printf(\ if(a>b)

{t=a;a=b;b=t;} if(a>c)

{t=a;a=c;c=t;} if(a>d)

{t=a;a=d;d=t;} if(b>c)

{t=b;b=c;c=t;} if(b>d)

{t=b;b=d;d=t;} if(c>d)

{t=c;c=d;d=t;}

printf(\排序结果如下:\\n\

printf(\ %d %d %d\\n\}

5.10有4个圆塔,圆心分别为(2,2),(-2,2),(2,-2),(-2,-2),圆半径为1。见图4.4。这4个塔的高度分别为10m。塔以外无建筑物。今输入任一点的坐标,求该点的建筑高度(塔外的高度为0)。 解:程序如下 main ( ) { int h=10;

float x1=2,y1=2,x2=-2,y2=2,x3=-2,y3=-2,x4=2,y4=-2,x,y,d1,d2,d3,d4; printf(“请输入一个点(x,y):”);

scanf(“%f,%f”,&x,&y); /*求该点到各中心点的距离*/

d1=(x-x1)*(x-x1)+(y-y1)* (y-y1);

d2=(x-x2)*(x-x2)+(y+y2)* (y+y2; d3=(x+x3)*(x+x3)+(y-y3)* (y-y3); d4=(x+x4)*(x+x4)+(y+y4)* (y+y4);

if (d1>1 && d2>1 && d3>1 && d4>1) h=0; /*判断该点是否在塔外*/

printf(“该点高度为%d”,h); }

运行情况:

请输入一个点(x,y):0.5,0.7↙ 该点高度为0

请输入一个点(x,y):2.1,2.3↙ 该点高度为10

第6章 循环控制

6.1输入两个正整数m和n,求其最大公约数和最小公倍数。 解:用辗转相除法求最大公约数 main ( )

{ int p,r,n,m,temp;

printf(“请输入两个正整数n,m:”); scanf(“%d,%d”,&n,&m); if (n

{ temp=n; n=m;

m=temp; /*把大数放在n中,小数放在m中*/

}

p=n*m; /*先将m和n的乘积保存在p中,以便求最小公倍数时用*/ while (m!=0) /*求m和n的最大公约数*/ { r=n%m; n=m; m=r;

}

printf(“它们的最大公约数为:%d\\n”,n);

printf(“它们的最小公倍数为:%d\\n”,p/n); /*p是原来两个整数的乘积*/ }

运行情况:

请输入两个正整数:12,8↙

它们的最大公约数为:4 它们的最小公倍数为:24

6.2输入一行字符,分别统计出其中英文字母,空格,数字和其它字符的个数。 解:

#include main ( ) { char c;

int letter=0,space=0,digit=0,other=0; printf(“请输入一行字符:\\n”);

while((c=getchar( ))!=?\\n?)

{ if (c>=?a? && c<=?z? || c>=?A? && c<=?Z?)

letter++; else if (c==? ?)

space++;

else if (c>=?0? && c<=?9?) digit++; else other++;

}

printf(“字母数=%d,空格数=%d,数字数=%d,其它字符数=%d\\n”,letter,space,digit,other); }

运行情况: 请输入一行字符:

My teacher?s address is “#123 Beijing Road,Shanghai”.

字母数:38,空格数:6,数字数:3,其它字符数:6

6.3

求Sn=a+aa+aaa+?+aa?a之值,其中a是一个数字。例如:2+22+222+2222+22222 n个a (此时n=5),n由键盘输入。 解: main ( )

{ int a,n,i=1,sn=0,tn=0; printf(“a,n= :”);

scanf(“%d,%d”,&a,&n); while (i<=n)

{ tn=tn+a; /*赋值后的tn为i个a组成数的值*/ sn=sn+tn; /*赋值后的sn为多项式前I项之和*/

a=a*10;

i++;

printf(“a+aa+aaa+?=%d\\n”,sn); }

运行情况: a,n:2,5↙

a+aa+aaa+?=24690

6.4求∑n!(即求1+2!+?+20!)。 解: main ( ) {float s=0,t=1; int n;

for (n=1;n<=20;n++) {

t=t*n; /*求n!*/

s=s+t; /*将各项累加*/ }

printf(“1!+2!+?+20!=%e\\n”,s); }

运行结果:

1!+2!+?+20!=2.56133e+18

注意:s不能定义为int型,因为int型数据的范围是-32768~32767;也不能定义为long型,因为long型数据的范围为-21亿~21亿,无法容纳求得的结果。 6.5求

1005010?k?1k??k?1k?2?k

k?11解:

#include \#include \

main()

{

int n1=100,n2=50,n3=10,k;

float s1=0,s2=0,s3=0; for(k=1;k<=n1;k++) s1+=k;

for(k=1;k<=n2;k++) s2+=k*k; for(k=1;k<=n3;k++) s3+=1.0/k;

printf(\ getch(); }

6.6打印出所有的“水仙花数”。

所谓“水仙花数”是指一个3位数,其各位数字的立方和等于该数本身。例如,153是一个“水仙花数”,因为153=1+5+3。 解:

main ( ) { int i,j,k,n;

printf(““水仙花数”是:”); for (n=100;n<1000;n++)

{i=n/100; j=n/10-i*10; k=n;

if (n==i*i*i+j*j*j+k*k*k) printf(“M”,n);

}

printf(“\\n”); }

运行结果:

“水仙花数“是:153 370 371 407

3

3

3

6.7一个数如果恰好等于它的因子之和,这个数就称为“完数“。例如,6的因子为1,2,3,而6=1+2+3,因此6是“完数”。编程序找出1000以内的所有“完数”,并按下面的格式输出其因子:6 Its factors are 1,2,3 解:方法一:

#define M 1000 /*定义寻找范围*/ main ( )

{ int k1,k2,k3,k4,k5,k6,k7,k8,k9,k10;

if (s1[i]==?\\0? && s2[i]==?\\0?) resu=0; else

resu=s1[i]-s2[i];

printf(“\\n result:%d. \\n”,resu); }

运行情况如下: Input string1:aid↙ Input string2:and↙ result:-5

7.15编写一个程序,将字符数组s2的全部字符拷贝到字符数组s1中,不用strcpy函数。拷贝时,’\\0’也要拷过去,’\\0’后面的字符不拷贝。 解: 程序如下: # include main ( )

{ char s1[80],s2[80]; int i;

printf(“Input s2:”); scanf(“%s”,s2);

for (i=0;i<=strlen(s2);i++) s1[i]=s2[i];

printf(“s1: %s\\n”,s1); }

运行情况如下: Input s2:student↙ s1: student

第8章 函数

8.1写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果,两个整数由键盘输入。

解:设两个整数为u和v,用碾转相除法求最大公约数的算法如下:

最小公倍数=u×v/最大公约数。据此写出程序: int hcf(int u,int v) {int t,r; if (v>u)

{t=u;u=v;v=t;} while ((r=u%v)!=0) {u=v; v=r;} return(v); }

int lcd(int u,int v,int h) {

return(u*v/h); }

main ( ) {int u,v,h,l;

scanf(“%d,%d”,&u,&v); h=hcf(u,v);

printf(“H.C.F=%d\\n”,h); l=lcd(u,v,h);

printf(“L.C.D=%d\\n”,l); }

运行结果如下: 24,16↙ H.C.F=8 L.C.D=48 8.2

求方程ax+bx+c=0的根,用3个函数分别求当b-4ac大于0,等于0和小于0时的根,并输出结果。从主函数输入a,b,c的值。 解:程序如下: # include

float x1,x2,disc,p,q;

greater_than_zero(float a,float b) /*定义一个函数,用来求disc>0时方程的根*/ {x1=(-b+sqrt(disc))/(2*a) x2=(-b-sqrt(disc))/(2*a) }

equal_to_zero(float a,float b) /*定义一个函数,用来求disc=0时方程的根*/

2

2

{

x1=x2=(-b)/(2*a);

}

smaller_than_zero(float a,float b) /*定义一个函数,用来求disc<0时方程的根*/ {

p=-b/(2*a) q=sqrt(disc)/(2*a); } main ( ) {

float a,b,c;

printf(“\\nInput a,b,c:”);

scanf(“%f,%f,%f”,&a,&b,&c);

printf(“\\nequation:%5.2f*x*x+%5.2f*x+%5.2f=0\\n”,a,b,c); disc=b*b-4*a*c; printf(“root:\\n”); if (disc>0) {

great_than_zero(a,b);

printf(“x1=%5.2f\\tx2=%5.2f\\n\\n”,x1,x2); }

else if (disc==0)

{equal_to_zero(a,b);

printf(“x1=%5.2f\\tx2=%5.2f\\n\\n”,x1,x2); }

else

{smaller_than_zero(a,b);

printf(“x1=5.2f+5.2fi\\tx2=%5.2f-%%5.2fi\\n”,p,q,p,q); }

}

运行结果:

Input a,b,c:1,2,1↙

equation:1.00*x*x+2.00*x+1.00=0 root:

x1=-1.00x2=-1.00

8.3写一个判素数的函数,在主函数输入一个整数,输出是否素数的信息。 解: main ( )

{int prime(int); /*函数原型声明*/ int n;

printf(“\\nInput an integer:”); if (prime(n))

printf(“\\n %d is a prime.”,n); else

printf(“\\n %d is not a prime.”,n); }

int prime(int n)

{int flag=1,i;

for (i=2;i

flag=0; return(flag); }

运行结果:

Input an integer:17↙ 17 is a prime.

8.4写一函数,使给定的一个二维数组(3×3)转置,即行列互换。 解: # define N 3

int array[N][N];

convert(int array[3][3]) /*定义转置数组的函数*/ {int i,j,t;

for (i=0;i

{t=array[i][j];

array[i][j]=array[j][i]; array[j][i]=t; }

} main ( ) {int i,j;

printf(“Input array:\\n”); for (i=0;i

for (i=0;i

{for (j=0;j

printf(“]”,array[i][j]); printf(“\\n”); } }

convert (array);

{printf(“convert array:\\n”); for (i=0;i

{for (j=0;j

printf(“%sd”,array[i][j]); printf(“\\n”); } }

运行结果: Input array:

1 2 3 4 5 6 7 8 9↙ original array: 1 2 3 4 5 6 7 8 9 convert array: 1 4 7 2 5 8 3 6 9

8.5写一函数,使输入的一个字符串按反序存放,在主函数中输入和输出字符串。 解:

main ( )

{int inverse (char str[ ]); /*函数原型声明*/ char str[100]; printf(“Input string:”); scanf(“%s”,str);

inverse(str);

printf(“Inverse string:%s\\n”,str); }

int inverse (char str[ ]) /*函数定义*/ {char t; int i,j;

本文来源:https://www.bwwdw.com/article/1pxd.html

Top