习题答案

Posted 曦文先生

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了习题答案相关的知识,希望对你有一定的参考价值。

1.请画出例5.6中给出的3个程序段的流程图

解析:没啥解说的,代码很简单,熟练掌握流程图就好了。上图!

(1)流程图如下

(2)流程图如下

(3)流程图如下

 2.请补充例5. 7程序,分别统计当“fabs(t)>= 1e- 6”和“fabs(t)> = 1e- 8”时执行循环体的次数。

解析:我看到其他的答案中写的很复杂,还有些答案里重写了一个代码,我很不理解这种行为,我觉得完全没有意义。实现计数只要加一个计数器就可以了,放代码!

(1)fabs(t)>= 1e- 6

int main()

	int sign = 1;
	double pi = 0.0, term = 1.0, n = 1.0;
	int count = 0;
	while (fabs(term) >= 1e-6)
	
		pi = pi + term;
		n = n + 2;
		sign = -sign;
		term = sign / n;
		++count;
	
	pi *= 4;
	printf("pi=%10.8f\\n", pi);
	printf("共运算了%d次\\n", count);
	return 0;

 运行结果:

 (2)fabs(t)>= 1e- 8

int main()

	int sign = 1;
	double pi = 0.0, term = 1.0, n = 1.0;
	int count = 0;
	while (fabs(term) >= 1e-8)
	
		pi = pi + term;
		n = n + 2;
		sign = -sign;
		term = sign / n;
		++count;
	
	pi *= 4;
	printf("pi=%10.8f\\n", pi);
	printf("共运算了%d次\\n", count);
	return 0;

运算结果:

3.输人两个正整数m和n,求其最大公约数和最小公倍数

解析:这题难点在于求最大公约数,最大公约数我们可以用最简单粗暴的辗转相除法解出来,辗转相除法可以跳链接C语言——辗转相除法求最大公约数和最小公倍数,至于最小公倍数有一个性质大家可以记一下:两个自然数的乘积等于这两个自然数的最大公约数和最小公倍数的乘积。放代码!

int main()

		int m = 0;
		int n = 0;
		int temp = 0;
		printf("请输入正整数m和n的值:>");
		scanf("%d %d", &m, &n);
		int sum = m * n;
		if (m < n)
		
			temp = m;
			m = n;
			n = temp;
		
		while (1)
		
			if (m % n == 0)
			
				break;
			
			m = n;
			n = m % n;

		
		printf("\\n最大公约数为:%d\\n", n);
		printf("\\n最小公倍数为:%d\\n", sum/n);
	return 0;

 运行结果:

4.输人一行字符,分别统计出其中英文字母、空格、数字和其他字符的个数。 

解析:这一题我个人觉得比较难,我一直没想到getchar能玩的那么花,详情见getchar的使用。这里主要是使用到了getchar清理缓冲区的特性,getchar()会从输入缓冲区去读取内容,也就是说我们把所有的内容都输入完成并且按下了Enter键后,我们的输入才被送进去了输入缓冲区,这个时候,getchar()会从输入缓冲区读取一个字符,这时候我们就可以给getchar套上while循环实现多字符读取。放代码!

int main()

	char c;
	int eng_char = 0, space_char = 0, digit_char = 0, other_char = 0;
	printf("请输入一行字符:");
	while ((c = getchar()) != '\\n')
	
		if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
		
			eng_char++;//定义eng_char为英文字母的个数,初始值为0
		
		else if (c == ' ')
		
			space_char++;//定义space_char为空格字符的个数,初始值为0
		
		else if (c >= '0' && c <= '9')
		
			digit_char++;//定义digit_char为数字字符的个数,初始值为0
		
		else
		
			other_char++;//定义other_char为其他字符的个数,初始值为0
		
	
	printf("英文字母数量:%d\\n空格数量:%d\\n数字数量:%d\\n其他字符数量:%d\\n", 
		eng_char, space_char, digit_char, other_char);
	return 0;

运行结果:

注意:这里其他字符数量为10不是错误,是因为这里使用的是中文字符,中文字符在ASCⅡ码中占两个字节。

5.求S n 的值 

解析:这一题是找规律题目,从题目中可以看出这里是2+22+222……的形式,22就可以分解成20+2,222就可以分解成200+22,同理2222分解成2000+222。后项等于前项加2*1e(n-1)。语言表达比较抽象,直接上代码,用代码表达。

void my_sum(int a, int n)

	int i = 0;
	int aa = 0;
	int sum = 0;
	for (i = 0;i <= n-1;i++)
	
		aa +=  a*pow(10, i);
		sum +=  aa;
	
	printf("运算结果为%d\\n", sum);

int main()

	while (1)
	
		int a = 0;
		int n = 0;
		printf("请输入a和n的数值:>");
		scanf("%d %d", &a, &n);
		my_sum(a, n);
	
	return 0;

运行结果:

6.求1-20阶乘和

 解析:这一题就是两个循环,一个循环是求某一个值得阶乘,另一个循环是求阶乘和。但是,要注意的是,这个20!太大了,用double、long double、long long int输出的答案可能各不相同。

int main()

	double sum = 0.0;
	for (int i = 1; i <= 20; i++)
	
		double count = 1.0;
		for (int j = 1; j <= i; j++)
		
			count *= j;
		
		sum += count;
	
	printf("计算结果为%lf", sum);
	return 0;

运算结果:

7.求三个阶乘和

int main()

	double fraction_sum = 0.0;
	int square_sum = 0;
	int sum_sum = 0;
	for (int i = 1; i <= 100; i++)
	
		if (i <= 10)
		
			fraction_sum += 1.0 / i;
		
		if (i <= 50)
		
			square_sum += i*i;
		
		sum_sum += i;
	
	printf("%f", fraction_sum + square_sum + sum_sum);
	return 0;

运行结果:

8.输出所有的“水仙花数”,所谓“水仙花数”是指一个3位数,其各位数字立方和等于该数本身。

解析:这一题主要难点在于如何提取数字的百位,十位和个位,一般可以用整数除法和取模来获得,放代码!

int main()

	int Hundredth, Ten, Bit;
	for (int i = 100; i <= 999; i++)
	
		Hundredth = i / 100;
		Ten = (i / 10) % 10;
		Bit = i % 10;
		if ((Hundredth * Hundredth * Hundredth)
			+ (Ten * Ten * Ten) + (Bit * Bit * Bit) == i)
			printf("%d\\n", i);
	
	return 0;

 运行结果:

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

解析:这一题难点在于如何确定什么是完数,完数有几个要求要满足:①除数,被除数,商都是整数;②因子是商;③因子之和等于除数;放代码!

	/*
	一个数如果恰好等于它的因子之和,这个数就称为“完数”。
	例如,6的因子为1,2,3,而6=1+2+3,因此6是“完数”。
	编程序找出1000之内的所有完数,并按下面格式输出其因子:
	*/
int main()

	int num, factor, sum;
	for (num = 2; num <= 1000; num++)
	
		sum = 1;
		for (factor = 2; factor <= num / 2; factor++)
		
			if (num % factor == 0)
			
				sum += factor;
			
		
		if (sum == num)
		
			printf("%d:>1 ", num);
			for (factor = 2; factor <= num / 2; factor++)
			
				if (num % factor == 0)
				
					printf("%d ", factor);
				

			
			printf("\\n");
		
	
	return 0;

运算结果:

10.有一个分数序列,求出这个数列的前20项之和。

解析:这一题的难点在规律,代码实现并不难。我们可以看到第一个数的分子是第二个数的分母,第二个数的分子是前一个数的分子分母之和。放代码!

int main()

	double num1 = 1.0, num2 = 2.0;
	double sum = 0.0, temp = 0.0;
	for (int i = 0; i < 20; i++)
	

		sum += num2 / num1;

		temp = num1 + num2;

		num1 = num2;

		num2 = temp;

	
	printf("前二十项和为%f", sum);
	return 0;

 运行结果:

11.一个球从100m高度自由落下,每次落地后反弹回原高度的一半,再落下,再反弹。求它在第10次落地时共经过多少米,第10次反弹多高。

 解析:这一题没有难点,但是有一个易错点,这个球无论是否弹起都至少会有一个100米的自由落体。放代码!

int main()

	double high = 100.0;
	double sum = high;//无论是否弹起都会有100米的路径
	for (int i = 0; i < 10; i++)
	
		sum += high;
		high /= 2;//每次落体弹起高度衰减为原来一半

	
	printf("第10次落地时共经过%f米\\n第10次反弹%f米", sum,high);
	return 0;

运行结果:

12.猴子吃桃问题。猴子第1天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第2天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,就只剩一个桃子了。求第1天共摘多少个桃子。

 解析:这题我们先顺向分析,假设第一天摘了N个桃子,吃了(N/2)-1个桃子,第10天时只剩一个桃子,所以它实际上只吃了九天,我们这里逆向循环九次就可以了。放代码!

int main()

	int num = 1;
	for (int i = 9; i > 0; i--)
	
		num = (num + 1) * 2;
	
	printf("第一天摘了%d个桃子", num);
	return 0;

运行结果:

 13.用迭代法求 。

求平方根的迭代公式为要求前后两次求出的x的差的绝对值小于

 解析:这个题目是一个数学题,这里已经提供了公式我们只要反复循环套公式就可以了。放代码!

int main()

	double x1 = 0.0, x2 = 0.0 , a = 0.0;
	printf("请输入一个正数:>");
	scanf("%lf", &a);
	x1 = a / 2;
	x2 = (x1 + a / x1) / 2;
	while (fabs(x1 - x2) >= 1e-5)
	
		x1 = x2;
		x2 = (x1 + a / x1) / 2;
	 
	printf("%.0lf的平方根为%lf", a, x1);
	return 0;

运行结果:

 14.用牛顿迭代法求下面方程在1.5附近的根:

解析:还是数学题,难不难在于你会不会牛顿迭代法。。。没啥说的直接放代码!

int main()

	double x0 = 0.0, x1 = 0.0, f = 0.0, f1 = 0.0;
	x1 = 1.5;
	while (fabs(x1 - x0) >= 1e-5)
	
		x0 = x1;
		f = ((2 * x0 - 4) * x0 + 3) * x0 - 6;
		f1 = (6 * x0 - 8) * x0 + 3;
		x1 = x0 - (f / f1);
	
	printf("%f", x1);
	return 0;

 运算结果:

15.用二分法求下面方程在(-10,10)的根:

解析:这还是数学题,二分法实际上就是猜数字,首先猜测一个中间值,如果目标值比中间值大,则说明比中间值小的都不符合要求,把中间值赋值给范围下界,同样的如果目标值比中间值小,则说明比中间值大的都不符合要求,把中间值赋值给范围上界。放代码!

int main()

	double left = -10, right = 10, mid, sum = 1;
	while (fabs(sum) >= 1e-5)
	
		mid = (left + right) / 2;
		sum = (mid * (mid * (2 * mid - 4) + 3) - 6);
		if (sum > 0)
		
			right = mid;
		
		if (sum < 0)
		
			left = mid;
		
	
	printf("该方程的根为%f\\n", mid);
	return 0;

运算结果:

 16.输出以下图案:

 解析:这一题的难点在于找规律,星星符号、空格、行数之间的规律是啥。首先我们可以看到星星的排列是1357531,第0行3空格,第1行2空格,第2行1空格,第3行0空格。这里我们就可以看到行数和空格的关系是空格 = 3-行数。找到规律我们就可以开始写代码了,放代码!

注:代码长的时候最好不要团在一起,封装成函数是最合适的。

void print1()

	for (int i = 0; i < 4; i++)
	
		for (int j = 0; j <= 3-i ; j++)
		
			printf(" ");
		
		for (int j = 0; j <= 2*i; j++)
		
			printf("*");
		
		printf("\\n");
	


void print2()

	for (int i = 2; i >= 0; i--)
	
		for (int j = 0; j <= 3 - i; j++)
		
			printf(" ");
		
		for (int j = 0; j <= 2 * i; j++)
		
			printf("*");
		
		printf("\\n");
	



int main()

		print1();
		print2();
	return 0;

运行结果:

17.两个乒乓球队进行比赛,各出3人。甲队为A,B,C 3人,乙队为X,Y,Z 3人。已抽签决定比赛名单。有人向队员打听比赛的名单,A说他不和X比,C说他不和X,Z比,请编程序找出3对赛手的名单。

解析:这题如果是口算相信大家都会算,所以这题的难点是如何让计算机来计算。暂时没有想法什么好的方法,这里只好用最简单最粗暴的方法——穷举法。放代码!

int main()

	//1、穷举A的三种情况
	for (int A = 'X'; A <= 'Z'; A++)
	
		//2、穷举B的三种情况
		for (int B = 'X'; B <= 'Z'; B++)
		
			//3、穷举C的三种情况
			for (int C = 'X'; C <= 'Z'; C++)
			
				//4、排除已知条件
				if (A != 'X' && C != 'X' && C != 'Z' && A != B && A != C && C != B)
					printf("A对战%c\\nB对战%c\\nC对战%c\\n", A, B, C);
			
		
	
	return 0;

运行结果:

以上是关于习题答案的主要内容,如果未能解决你的问题,请参考以下文章

C语言学习笔记

推荐 3 个学习C语言算法与习题的平台

《C++Primer习题集(第5版)》,对使用C Primer(第五版)学习C 程序设计语言的读者来说是一本非常理想的参考书。

C语言习题答案(仅参考)

数据结构(C语言版)课后习题全套完整答案及详解 (答案由李冬梅老师撰写)

谭浩强版C语言程序设计(第三版)课后习题完整答案附源码--高等教育出版社