C/C++教程

《C语言程序设计》(谭浩强第五版) 第3章 最简单的的C程序设计——顺序程序设计 习题解析与答案

本文主要是介绍《C语言程序设计》(谭浩强第五版) 第3章 最简单的的C程序设计——顺序程序设计 习题解析与答案,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

你也可以上程序咖(https://meta.chengxuka.com),打开大学幕题板块,不但有答案,讲解,还可以在线答题。

WX20220412-135428@2x

题目1:假如我国国民生产总值的年增长率为7%,计算10年后我国国民生产总值与现在相比增长多少百分比。计算公式为:
$$
p=(1+r)^n
$$

r 为年增长率,n 为年数,p为与现在相比的倍数。

解:从主教材附录D(库函数)可以查到:可以用pow函数求$y^x$的值,调用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;
}

运行结果:

WX20220321-160340@2x

即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)$

n年期本息和: $P=1000* (1+n* r);$
存n次1年期的本息和:$P=1000* (1+r)^n;$

说明: $1000*(1+\frac{r}{4})$ 是一个季度的本息和。

解:设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;
}

运行结果:

WX20220322-092435@2x

讨论:
(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;

由于采用了双精度变量,得到的运算结果会更精确些,最后几位数字与上面的有些差别。

WX20220322-093327@2x

(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种方案得到的本息和

这时的输出结果如下:

WX20220322-093726@2x

题目3:购房从银行贷了一笔款d,准备每月还款额为p,月利率为r,计算多少月能还清。设d为300 000元,p为6000元,r为1%。对求得的月份取小数点后一位,对第2位按四舍五入处理。

提示:计算还清月数m的公式如下:
$$
m=\frac{log p-log(p-d*r)}{log(1+r)}
$$

可以将公式改写为
$$
m=\frac{log(\frac{p}{p-d*r})}{log(1+r)}
$$

C的库函数中有求对数的函数log10,是求以10为底的对数,log(p)表示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;
}

运行结果:

WX20220322-100200@2x

即需要69.7个月才能还清。为了验证对第2位小数是否已按四舍五入处理,可以将程序第6行中的“%6.1f”改为“%6.2f"”。此时的输出为

WX20220322-100411@2x

题目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)运行时会输出什么信息?为什么?

解:运行时输出

WX20220322-100503@2x

第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;
}

解:按如下方式在键盘上输入:

WX20220322-104625@2x

第3行是输出的结果。

注意:在输入8.5和71.82两个实数给x和y后,应紧接着输入字符A,中间不要有空格,,由于A是字母而不是数字,系统在遇到字母A时就确定输入给y的数值已结束。字符A就送到下一个scanf语句中的字符变量c1。如果在输入8.5和71.82两个实数后输入空格符,会怎么样呢?情况如下:

WX20220322-110238@2x

这时71.82后面输入的空格字符就被c1读入,c2读入了字符A。在输出c1时就输出空格,输出c2的值为A。

如果在输入8. 5和71.82两个实数后按回车键,会怎么样呢?情况如下:

WX20220322-110453@2x

上面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;
}

运行结果:

WX20220322-110914@2x

题目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;
}

运行结果:

WX20220322-121607@2x

说明:如果用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;
}

运行结果:

WX20220322-112812@2x

注意:若连续用两个getchar函数,输入字符时a和b之间没有空格,连续输入。

如果分两行输入:

WX20220322-113023@2x

结果会怎样?

运行结果:

WX20220322-113109@2x

第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;
}

运行结果:

WX20220322-120432@2x

程序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;
}

运行结果:

WX20220322-121755@2x

程序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;
}

运行结果:

WX20220322-120921@2x

请注意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'。

WX20220322-121428@2x

这篇关于《C语言程序设计》(谭浩强第五版) 第3章 最简单的的C程序设计——顺序程序设计 习题解析与答案的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!