《C语言程序设计》(谭浩强第五版) 第3章 最简单的的C程序设计——顺序程序设计 习题解析与答案
你也可以上程序咖(https://meta.chengxuka.com),打开大学幕题板块,不但有答案,讲解,还可以在线答题。
题目1:假如我国国民生产总值的年增长率为7%,计算10年后我国国民生产总值与现在相比增长多少百分比。计算公式为:
p
=
(
1
+
r
)
n
p=(1+r)^n
p=(1+r)n
r 为年增长率,n 为年数,p为与现在相比的倍数。
解:从主教材附录D(库函数)可以查到:可以用pow函数求 y x y^x yx的值,调用pow函数的具体形式是pow(x,y)。在使用pow函数时需要在程序的开头用# include指令将<math.h>头文件包含到本程序模块中。可以用下面的程序求出10年后国民生产总值是现在的多少倍。
答案代码:
#include <stdio.h>
#include <math.h>
int main()
{
float p, r, n;
r = 0.07;
n = 10;
p = pow(1 + r, n);
printf("p= %f\n", p);
return 0;
}
运行结果:
即10年后国民生产总值是现在的1.967151倍。
题目2:存款利息的计算。有1000元,想存5年,可按以下5种办法存:
(1) 一次存5年期。
(2) 先存2年期,到期后将本息再存3年期。
(3) 先存3年期,到期后将本息再存2年期。
(4) 存1年期,到期后将本息再存1年期,连续存5次。
(5) 存活期存款。活期利息每-季度结算一次。
2017年的银行存款利息如下:
1年期定期存款利息为1.5%;
2年期定期存款利息为2.1%;
3年期定期存款利息为2.75%;
5年期定期存款利息为3%;
活期存款利息为0.35%(活期存款每一季度结算一次利息)。
如果 r 为年利率,n 为存款年数,则计算本息和的公式如下:
1年期本息和: P = 1000 ∗ ( 1 + r ) P=1000* (1+r) P=1000∗(1+r)
n年期本息和:
P
=
1000
∗
(
1
+
n
∗
r
)
;
P=1000* (1+n* r);
P=1000∗(1+n∗r);
存n次1年期的本息和:
P
=
1000
∗
(
1
+
r
)
n
;
P=1000* (1+r)^n;
P=1000∗(1+r)n;
说明: 1000 ∗ ( 1 + r 4 ) 1000*(1+\frac{r}{4}) 1000∗(1+4r) 是一个季度的本息和。
解:设5年期存款的年利率为r5,3年期存款的年利率为r3,2年期存款的年利率为r2,1年期存款的年利率为rl,活期存款的年利率为r0。
设按第1种方案存款5年得到的本息和为p1,按第2种方案存款5年得到的本息和为p2,按第3种方案存款5年得到的本息和为p3,按第4种方案存款5年得到的本息和为p4,按第5种方案存款5年得到的本息和为p5。
答案代码:
#include <stdio.h>
#include <math.h>
int main()
{
float r5, r3, r2, r1, r0, p, p1, p2, p3, p4, p5;
p = 1000;
r5 = 0.03;
r3 = 0.0275;
r2 = 0.021;
r1 = 0.015;
r0 = 0.0035;
p1 = p * (1 + r5 * 5); //一次存5年期
p2 = p * (1 + 2 * r2) * (1 + 3 * r3); //先存2年期,到期后将本息再存3年期
p3 = p * (1 + 3 * r3) * (1 + 2 * r2); //先存3年期,到期后将本息再存2年期
p4 = p * pow(1 + r1, 5); //存1年期,到期后将本息再存1年期,连续存5次
p5 = p * pow(1 + r0 / 4, 4 * 5); //存活期存款,活期利息每一季度结算一次
printf("p1= %f\n", p1); //输出按第1种方案得到的本息和
printf("p2= %f\n", p2); //输出按第2种方案得到的本息和
printf("p3= %f\n", p3); //输出按第3种方案得到的本息和
printf("p4= %f\n", p4); //输出按第4种方案得到的本息和
printf("p5= %f\n", p5); //输出按第5种方案得到的本息和
return 0;
}
运行结果:
讨论:
(1) 程序在编译时出现警告(warning),并告知原因是“‘=': truncation from ’ const double ’ to ‘float’”(在执行赋值时,出现将双精度常量转换为单精度的情况)。这是由于VisualC++6.0在编译时把实常数(如程序中的利率)全部按双精度数处理,因此在向r5,r3等float型变量赋值时,就出现将双精度数赋给单精度变量的情况,这样可能会损失一些精度,故向用户提醒,请用户考虑是否要修改。警告只是提醒,程序可以正常运行,但得到的结果可能会出现一些误差,如果用户认为误差可以容忍,可不理会警告,继续进行连接和运行。
(2) 如果不想出现上面的警告,可以将第4行各变量改为double型,即
double r5,r3,r2 ,r1,r0,p,p1 ,p2 ,p3,p4,p5;
由于采用了双精度变量,得到的运算结果会更精确些,最后几位数字与上面的有些差别。
(3) 输出运行结果时,得到6位小数,连同整数部分有10 位数字,而一个float 型变量只能保证6位有效数字,后面几位是无意义的。而且在输出款额时,入们一般只要求精确到两位小数(角、分),因此可以在printf 函数中用%10.2格式符输出。最后5个语句可改为
printf("p1=%10.2f\n", p1); //输出按第1种方案得到的本息和
printf("p2=%10.2f\n", p2); //输出按第2种方案得到的本息和
printf("p3=%10.2f\n", p3); //输出按第3种方案得到的本息和
printf("p4=%10.2f\n", p4); //输出按第4种方案得到的本息和
printf("p5=%10.2f\n", p5); //输出按第5种方案得到的本息和
这时的输出结果如下:
题目3:购房从银行贷了一笔款d,准备每月还款额为p,月利率为r,计算多少月能还清。设d为300 000元,p为6000元,r为1%。对求得的月份取小数点后一位,对第2位按四舍五入处理。
提示:计算还清月数m的公式如下:
m
=
l
o
g
p
−
l
o
g
(
p
−
d
∗
r
)
l
o
g
(
1
+
r
)
m=\frac{log p-log(p-d*r)}{log(1+r)}
m=log(1+r)logp−log(p−d∗r)
可以将公式改写为
m
=
l
o
g
(
p
p
−
d
∗
r
)
l
o
g
(
1
+
r
)
m=\frac{log(\frac{p}{p-d*r})}{log(1+r)}
m=log(1+r)log(p−d∗rp)
C的库函数中有求对数的函数log10,是求以10为底的对数,log§表示log p。
解:根据以上公式可以很容易写出以下程序。
答案代码:
#include <stdio.h>
#include <math.h>
int main()
{
float d = 300000, p = 6000, r = 0.01, m;
m = log10(p / (p - d * r)) / log10(1 + r);
printf("m=%6.1f\n", m);
return 0;
}
运行结果:
即需要69.7个月才能还清。为了验证对第2位小数是否已按四舍五入处理,可以将程序第6行中的“%6.1f”改为“%6.2f"”。此时的输出为
题目4:分析下面的程序:
#include <stdio.h>
int main()
{
char c1, c2;
c1 = 97;
c2 = 98;
printf("c1= %c,c2= %c\n", c1, c2);
printf("c1= %d,c2= %d\n", c1, c2);
return 0;
}
(1)运行时会输出什么信息?为什么?
解:运行时输出
第1行是将c1,c2按%c的格式输出,97是字符a的ASCII码,98是字符b的ASCII码。
第2行是将c1,c2按%d的格式输出,所以输出两个十进制整数。
(2)如果将程序第4,5行改为
c1=197;
c2= 198;
运行时会输出什么信息?为什么?
解:由于VisualC++6.0字符型数据是作为signed char类型处理的,它存字符的有效范围为0~127,超过此范围的处理方法,不同的系统得到的结果不同,因而用%c格式输出时,结果是不可预料的。
用%d格式输出时,输出c1=-59,c2=-58。这是按补码形式输出的,内存字节中第1位为1时,作为负数。59与197之和等于256,58与198之和也等于256。对此可暂不深究。
只要知道:用char类型变量时,给它赋的值应在0~127范围内。
(3)如果将程序第3行改为
int c1 ,c2;
运行时会输出什么信息?为什么?
解:如果给c1和c2赋的值是97和98,则输出结果与(1)相同。如果给c1和c2赋的值是197和198,则用%c输出时是不可预料的字符。用%d输出时,输出整数197和198,因为它们在int类型的有效范围内。
题目5:用下面的scanf函数输入数据,使a=3,b=7,x=8.5,y=71.82,c1=‘A’,c2=‘a’。在键盘上应如何输入?
#include <stdio.h>
int main()
{
int a, b;
float x, y;
char c1, c2;
scanf("a=%d b=%d", &a, &b);
scanf("%f %e", &x, &y);
scanf("%c %c", &c1, &c2);
printf("a=%d,b=%d,x=%f,y=%f,c1=%c,c2=%c\n", a, b, x, y, c1, c2);
return 0;
}
解:按如下方式在键盘上输入:
第3行是输出的结果。
注意:在输入8.5和71.82两个实数给x和y后,应紧接着输入字符A,中间不要有空格,,由于A是字母而不是数字,系统在遇到字母A时就确定输入给y的数值已结束。字符A就送到下一个scanf语句中的字符变量c1。如果在输入8.5和71.82两个实数后输入空格符,会怎么样呢?情况如下:
这时71.82后面输入的空格字符就被c1读入,c2读入了字符A。在输出c1时就输出空格,输出c2的值为A。
如果在输入8. 5和71.82两个实数后按回车键,会怎么样呢?情况如下:
上面3行是输入,在输入71. 82后按回车键。在这时“回车”被作为一个字符送到内存输入缓冲区,被c1读入(实际上c1读入的是回车符的ASCII码),字符A被c2读取,所以在执行printf函数输出c1时,就输出一个换行,在下一行输出逗号和c2的值A。
在用scanf函数输入数据时往往会出现一些意想不到的情况,例如在连续输入不同类型的数据(特别是数值型数据和字符数据连续输入)的情况。要注意回车符是可能被作为一个字符读入的。
通过此例,可以了解怎样正确进行输入数据。这些知识不能靠枯燥地死记规则,必须善于在实践中注意分析现象,不断总结经验。
题目6:请编程序将“China”译成密码,密码规律是:用原来的字母后面第4个字母代替原来的字母。例如,字母“A”后面第4个字母是“E" ,用“E”代替“A”。因此,“China"应译为“Glmre”。请编一程序,用赋初值的方法使cl,c2,c3,c4,c5这5个变量的值分为’C’,‘h’,‘i’,‘n’,‘a’ ,经过运算,使c1,c2,c3,c4,c5分别为’G’,‘l’,‘m’,‘r’,‘e’。 分别用putchar 函数和printf函数输出这5个字符。
解:答案代码:
#include <stdio.h>
int main()
{
char c1 = 'C', c2 = 'h', c3 = 'i', c4 = 'n', c5 = 'a';
c1 = c1 + 4;
c2 = c2 + 4;
c3 = c3 + 4;
c4 = c4 + 4;
c5 = c5 + 4;
printf("password is %c%c%c%c%c\n", c1, c2, c3, c4, c5);
return 0;
}
运行结果:
题目7:设圆半径r=1.5,圆柱高h=3,求圆周长、圆面积、圆球表面积、圆球体积、圆柱体积。用scanf输入数据,输出计算结果,输出时要求有文字说明,取小数点后2位数字。请编程序。
解:答案代码:
#include <stdio.h>
int main()
{
float h, r, l, s, sq, vq, vz;
float pi = 3.141526;
printf("请输入圆半径r,圆柱高h: ");
scanf("%f,%f", &r, &h); //要求输入圆半径r和圆柱高h
l = 2 * pi * r; //计算圆周长l
s = r * r * pi; //计算圆面积s
sq = 4 * pi * r * r; //计算圆球表面积sq
vq = 3.0 / 4.0 * pi * r * r * r; //计算圆球体积vq
vz = pi * r * r * h; //计算圆柱体积vz
printf("圆周长为: l=%6.2f\n", l);
printf("圆面积为: s=%6.2f\n", s);
printf("圆球表面积为: sq=%6.2f\n", sq);
printf("圆球体积为: v=%6.2f\n", vq);
printf("圆柱体积为: vz=%6.2f\n", vz);
return 0;
}
运行结果:
说明:如果用VisualC++ 6.0中文版对程序进行编译,在程序中可以使用中文字符串,在输出时也能显示汉字。如果用英文的C编译系统,则无法使用中文字符串,读者可以改用英文字符串。
题目8:编程序,用getchar函数读入两个字符给c1和c2,然后分别用putchar函数和printf函数输出这两个字符。思考以下问题:
(1)变量c1和c2应定义为字符型、整型还是二者皆可?
(2)要求输出cl和c2值的ASCII码,应如何处理?用putchar函数还是printf函数?
(3)整型变量与字符变量是否在任何情况下都可以互相代替?如:
char c1,c2;
与
int cl ,c2;
是否无条件地等价?
解:答案代码:
#include <stdio.h>
int main()
{
char c1, c2;
printf("请输入两个字符c1,c2:");
c1 = getchar();
c2 = getchar();
printf("用putchar语句输出结果为:");
putchar(c1);
putchar(c2);
printf("\n");
printf("用printf 语句输出结果为:");
printf("%c %c\n", c1, c2);
return 0;
}
运行结果:
注意:若连续用两个getchar函数,输入字符时a和b之间没有空格,连续输入。
如果分两行输入:
结果会怎样?
运行结果:
第1行是输入数据,输入a后按回车键。结果还未来得及输入b,程序马上输出了其下4行结果(包括2个空行)。
因为第1行将 a 和换行符输入到内存的输入缓冲区,因此c1得到a(ASCII码为97),c2得到换行符(ASCII码为10)。再用putchar函数输出c1,就输出了字符a,在输出c2时,就把换行符转换为回车和换行两个操作,输出一个换行,后面的printf(“\n”)又输出一个换行,所以就相当于输出一个空行,此行不显示任何字符。后面用printf 函数输出c1 和c2,同样也输出了字符a和一个空行。
注意:在用连续两个getchar输入两个字符时,只要输入了“a”然后回车,系统就会认为用户已输入了两个字符。所以应当连续输入ab两个字符然后再按回车键,这样就保证了c1和c2分别得到字符a和b。
下面回答思考问题:
(1) cl和c2可以定义为字符型或整型,二者皆可。
(2)可以用printf函数输出,在printf函数中用%d格式符,即
printf(" %d,%d\n" ,c1,c2);
(3)字符变量在计算机内占1个字节,而整型变量占2个或4个字节。因此整型变量在可输出字符的范围内(ASCII码为0~127的字符)是可以与字符数据互相转换的。如果整数在此范围外,不能代替。
为了进一步说明char型与int型数据的关系,请注意分析以下3个程序。
程序1:
#include <stdio.h>
int main()
{
int c1, c2; //定义整型变量c1,c2
printf("请输入两个整数c1,c2:");
scanf("%d,%d", &c1, &c2);
printf("按字符输出结果:\n");
printf("%c,%c\n", c1, c2);
printf("按ASCII码输出结果为:\n");
printf("%d,%d\n", c1, c2);
return 0;
}
运行结果:
程序2:
#include <stdio.h>
int main()
{
char c1, c2; // c1,c2定义为字符型变量
int i1, i2; //定义整型变量
printf("请输入两个字符c1,c2:");
scanf("%c,%c", &c1, &c2);
i1 = c1; //赋值给整型变量
i2 = c2;
printf("按字符输出结果:\n");
printf("%c,%c\n", i1, i2);
printf("按整数输出结果:\n");
printf("%d,%d\n", c1, c2);
return 0;
}
运行结果:
程序3:
#include <stdio.h>
int main()
{
char c1, c2; // c1,c2 定义为字符型
int i1, i2; // i1,i2定义为整型.
printf("请输入两个整数i1,i2:");
scanf("%d, %d", &i1, &i2);
c1 = i1; //将整数赋值给字符变量
c2 = i2;
printf("按字符输出结果:\n");
printf("%c,%c\n", c1, c2);
printf("按整数输出结果:\n");
printf("%d,%d\n", c1, c2);
return 0;
}
运行结果:
请注意i,i1和i2占2个或4个字节(Visual C++对它分配4个字节),而c1和c2是字符变量,只占1个字节。如果是unsigned char 类型,可以存放0~255的整数;如果是signed char类型,可以存放-128127范围内的整数。而现在输入给i1和i2的值已超过0255的范围,i1的值为289,在内存中i1的存储情况如图3.1(a)所示(为简单起见,用2个字节表示),在赋给字符变量c1时,只将其存储单元中最后一个字节(低8位)赋给c1,见
图3.1(b)。而图3.1(b)中的数据是整数33,是字符’!‘的ASCII码,所以用字符形式输出c1时,会输出字符’!‘。图3.2表示i2和c2的情况,c2的值为74,是字符’J’的ASCII码,因此,按字符形式输出c2时就输出字符j’。