c程序設計第五版譚浩強課後答案 第六章習題答案

c程序設計第五版課後答案譚浩強

1.請畫出例5.6中給出的3個程序段的流程圖

在這裏插入圖片描述

流程圖1:

請畫出例5.6中給出的3個程序段的流程圖

流程圖2:

請畫出例5.6中給出的3個程序段的流程圖

流程圖3:

請畫出例5.6中給出的3個程序段的流程圖

2.請補充例5. 7程序,分別統計當“fabs(t)>= le- 6”和“fabs(t)> = le- 8”時執行循環體的次數。

fabs(t)>= le- 6 ,示例代碼

# include <stdio.h>
# include <math.h>

int main()
{
	int sign = 1;
	double pi = 0.0, term = 1.0;
	int n = 0;

	while (fabs(term) >= 1e-6)
	{
		n++;
		term = 1.0 / (2 * n - 1)*sign;
		pi += term;
		sign = -sign;
	}
	pi *= 4;
	printf("pi的近似值是%lf\n", pi);
	printf("循環體循環了%d次\n", n);
	return 0;
}

運行截圖:

請補充例5. 7程序,分別統計當“fabs(t)>= le- 6”和“fabs(t)> = le- 8”時執行循環體的次數

fabs(t)> = le- 8,示例代碼

# include <stdio.h>
# include <math.h>

int main()
{
	int sign = 1;
	double pi = 0.0, term = 1.0;
	int n = 0;

	while (fabs(term) >= 1e-8)
	{
		n++;
		term = 1.0 / (2 * n - 1)*sign;
		pi += term;
		sign = -sign;
	}
	pi *= 4;
	printf("pi的近似值是%lf\n", pi);
	printf("循環體循環了%d次\n", n);
	return 0;
}

運行截圖:

請補充例5. 7程序,分別統計當“fabs(t)>= le- 6”和“fabs(t)> = le- 8”時執行循環體的次數

3.輸人兩個正整數m和n,求其最大公約數和最小公倍數

答案解析:

該題題目直接使用“輾轉相除法”來求解最大公約數,以除數和餘數反覆做除法運算,當餘數爲 0 時,就取得當前算式除數爲最大公約數。

最大公約數和最小公倍數之間的性質:兩個自然數的乘積等於這兩個自然數的最大公約數和最小公倍數的乘積。所以,當我們求出最大公約數,就可以很輕鬆的求出最小公倍數。

代碼示例:

#include <stdio.h>
int main()
{
	int  p, r, n, m, temp;
	printf("請輸入兩個正整數n,m:");
	scanf("%d%d,", &n, &m);
	//調整n保存較大的值
	if (n < m)
	{
		temp = n;
		n = m;
		m = temp;
	}

	p = n * m;
	while (m != 0)
	{
		r = n % m;
		n = m;
		m = r;
	}
	printf("它們的最大公約數爲:%d\n", n);
	printf("它們的最小公倍數爲:%d\n", p / n);
	return 0;
}

運行截圖:

輸人兩個正整數m和n,求其最大公約數和最小公倍數答案

4.輸人一行字符,分別統計出其中英文字母、空格、數字和其他字符的個數。

答案解析:

該題可以調用getchar函數,從stdin流中讀入一個字符,當輸入多個字符時,getchar()再執行時就會直接從緩衝區中讀取了。等同於getc(stdin)。所以,我們循環調用getchar,直到將標準輸入的內容讀到換行符\n爲止。同時判斷,讀取到的字符是英文字母、空格、數字或者其他字符,並計數;

代碼示例:

#include <stdio.h>

int main()
{
	char c;
	//定義eng_char爲英文字母的個數,初始值爲0
	//定義space_char爲空格字符的個數,初始值爲0
	//定義digit_char爲數字字符的個數,初始值爲0
	//定義other_char爲其他字符的個數,初始值爲0
	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++;
		}
		else if (c == ' ')
		{
			space_char++;
		}
		else if (c >= '0' && c <= '9')
		{
			digit_char++;
		}
		else
		{
			other_char++;
		}
	}

	printf("英文字母數量:%d\n空格數量:%d\n數字數量:%d\n其他字符數量:%d\n", eng_char, space_char, digit_char, other_char);
	return 0;
}

運行截圖:

輸人一行字符,分別統計出其中英文字母、空格、數字和其他字符的個數。答案

5.求SnS_n=a+aa+aaa+…+aa++ana\overbrace{aa+\dots+a}^{n個a} 之值,其中a是一個數字,n表示a的位數,n由鍵盤輸入。例如:

2+22+222+2222+22222 (此時n=5)

答案解析:

該題目可以將數字拆分爲 a * 10^n + 前一個數字,例如:

2 = 2 * 10^0 + 0 : 默認2的前一個數字爲0,也就是沒有任何值

22 = 2 * 10^1 + 2 : 22的前一個數字爲2

222 = 2*10^2 + 22 :222的前一個數字爲22

以此類推…

所以,在每次循環的時候,需要保存下,上一次結果的值,方便下一次計算

還需要使用到C庫當中使用的pow函數,來計算某個數的n次方,我們在該題目當中使用的是10的n次方,n隨着循環的次數,以此遞增。

代碼示例:

#include <stdio.h>
#include <math.h>

int main()
{
	//n爲a的個數
	int n;
	double a, prev_sum = 0.0, total_sum = 0.0;
	printf("請輸入a的值以及n的值: ");
	scanf("%lf %d", &a, &n);
	//循環n次求總和
	for (int i = 0; i < n; i++)
	{
		prev_sum += a * pow(10, i); 
		total_sum += prev_sum;
	}
	printf("總和爲:%lf\n", total_sum);
	return 0;
}

運行截圖:

求=a+aa+aaa+...+ 之值,其中a是一個數字,n表示a的位數,n由鍵盤輸入。例如:答案

6.求n=120n!\sum\limits_{n=1}^{20}n! (即求1!+2!+3!+4!+…+20!)。

答案解析:

該題需要從1循環到20,依次求出每一個數字階乘的結果。所以在代碼當中需要有兩個循環,大循環從1到20,保證1到20個數字都被循環到,小循環裏計算N階乘,累加求和。注意:對於20的階乘已經超出了int類型能過表示的數字範圍,所以在代碼當中使用double類型

代碼示例:

#include<stdio.h>

int main()
{
	double total_sum = 0;
	for(int i = 1; i <= 20; i++) 
	{
		double single_sum = 1;
		for (int j = i; j > 0; j--)
		{
			single_sum *= j;
		}
		total_sum += single_sum;
	}
	printf("1~20每個數字階乘總和爲:%lf\n",total_sum);
	return 0;
}

運行截圖:

求 (即求1!+2!+3!+4!+...+20!)。

7.k=1100k\sum\limits_{k=1}^{100}k +k=150k2\sum\limits_{k=1}^{50}{k}^2 +k=1101k\sum\limits_{k=1}^{10}{\frac{1}{k}}

答案解析:

對於k=1100k\sum\limits_{k=1}^{100}k而言,指的是求從1到100的和。每個數字爲整數,求和也爲整數

對於k=150k2\sum\limits_{k=1}^{50}{k}^2而言,指的是求從12到502的和。每個數字爲整數,求和也爲整數。

對於k=1101k\sum\limits_{k=1}^{10}{\frac{1}{k}}而言,指的是求從11\frac{1}{1}110\frac{1}{10}的和。每個數字不是整數,求和也不是整數。

綜上所述:求和結果不是整數,所以定義求和變量是需要定義爲帶有精度的變量double

該題目,最大的求和是從從1到100,所以需要一個循環,從1遍歷到100。針對第一種情況,則遍歷100次停下來。針對第二種情況,則遍歷50次的時候停下來,針對第三種情況,則遍歷10遍就停下來。

最後,在遍歷每一個數字的時候,針對三種不同的情況求和。最後將三種不同請求的和加起來就是總體的和

代碼示例:

#include <stdio.h>

int main()
{
	double total_sum = 0, sum1 = 0, sum2 = 0, sum3 = 0.0;
	for (int k = 1; k <= 100; k++)
	{
		sum1 += k;
		//遍歷50次就不在執行情況2
		if (k <= 50)
		{
			sum2 += k * k;
		}
		//遍歷10次就不在執行情況3
		if (k <= 10)
		{
			sum3 += 1.0 / k;
		}
	}
	total_sum = sum1 + sum2 + sum3;
	printf("三種情況求和結果爲:%lf\n", total_sum);
	return 0;
}

運行截圖:

![## c語言程序設計第五版課後答案譚浩強

1.請畫出例5.6中給出的3個程序段的流程圖

流程圖1:

請畫出例5.6中給出的3個程序段的流程圖

流程圖2:

請畫出例5.6中給出的3個程序段的流程圖

流程圖3:

請畫出例5.6中給出的3個程序段的流程圖

2.請補充例5. 7程序,分別統計當“fabs(t)>= le- 6”和“fabs(t)> = le- 8”時執行循環體的次數。

fabs(t)>= le- 6 ,示例代碼

# include <stdio.h>
# include <math.h>

int main()
{
	int sign = 1;
	double pi = 0.0, term = 1.0;
	int n = 0;

	while (fabs(term) >= 1e-6)
	{
		n++;
		term = 1.0 / (2 * n - 1)*sign;
		pi += term;
		sign = -sign;
	}
	pi *= 4;
	printf("pi的近似值是%lf\n", pi);
	printf("循環體循環了%d次\n", n);
	return 0;
}

運行截圖:

請補充例5. 7程序,分別統計當“fabs(t)>= le- 6”和“fabs(t)> = le- 8”時執行循環體的次數

fabs(t)> = le- 8,示例代碼

# include <stdio.h>
# include <math.h>

int main()
{
	int sign = 1;
	double pi = 0.0, term = 1.0;
	int n = 0;

	while (fabs(term) >= 1e-8)
	{
		n++;
		term = 1.0 / (2 * n - 1)*sign;
		pi += term;
		sign = -sign;
	}
	pi *= 4;
	printf("pi的近似值是%lf\n", pi);
	printf("循環體循環了%d次\n", n);
	return 0;
}

運行截圖:

請補充例5. 7程序,分別統計當“fabs(t)>= le- 6”和“fabs(t)> = le- 8”時執行循環體的次數

3.輸人兩個正整數m和n,求其最大公約數和最小公倍數

答案解析:

該題題目直接使用“輾轉相除法”來求解最大公約數,以除數和餘數反覆做除法運算,當餘數爲 0 時,就取得當前算式除數爲最大公約數。

最大公約數和最小公倍數之間的性質:兩個自然數的乘積等於這兩個自然數的最大公約數和最小公倍數的乘積。所以,當我們求出最大公約數,就可以很輕鬆的求出最小公倍數。

代碼示例:

#include <stdio.h>
int main()
{
	int  p, r, n, m, temp;
	printf("請輸入兩個正整數n,m:");
	scanf("%d%d,", &n, &m);
	//調整n保存較大的值
	if (n < m)
	{
		temp = n;
		n = m;
		m = temp;
	}

	p = n * m;
	while (m != 0)
	{
		r = n % m;
		n = m;
		m = r;
	}
	printf("它們的最大公約數爲:%d\n", n);
	printf("它們的最小公倍數爲:%d\n", p / n);
	return 0;
}

運行截圖:

輸人兩個正整數m和n,求其最大公約數和最小公倍數答案

4.輸人一行字符,分別統計出其中英文字母、空格、數字和其他字符的個數。

答案解析:

該題可以調用getchar函數,從stdin流中讀入一個字符,當輸入多個字符時,getchar()再執行時就會直接從緩衝區中讀取了。等同於getc(stdin)。所以,我們循環調用getchar,直到將標準輸入的內容讀到換行符\n爲止。同時判斷,讀取到的字符是英文字母、空格、數字或者其他字符,並計數;

代碼示例:

#include <stdio.h>

int main()
{
	char c;
	//定義eng_char爲英文字母的個數,初始值爲0
	//定義space_char爲空格字符的個數,初始值爲0
	//定義digit_char爲數字字符的個數,初始值爲0
	//定義other_char爲其他字符的個數,初始值爲0
	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++;
		}
		else if (c == ' ')
		{
			space_char++;
		}
		else if (c >= '0' && c <= '9')
		{
			digit_char++;
		}
		else
		{
			other_char++;
		}
	}

	printf("英文字母數量:%d\n空格數量:%d\n數字數量:%d\n其他字符數量:%d\n", eng_char, space_char, digit_char, other_char);
	return 0;
}

運行截圖:

輸人一行字符,分別統計出其中英文字母、空格、數字和其他字符的個數。答案

5.求SnS_n=a+aa+aaa+…+aa++ana\overbrace{aa+\dots+a}^{n個a} 之值,其中a是一個數字,n表示a的位數,n由鍵盤輸入。例如:

2+22+222+2222+22222 (此時n=5)

答案解析:

該題目可以將數字拆分爲 a * 10^n + 前一個數字,例如:

2 = 2 * 10^0 + 0 : 默認2的前一個數字爲0,也就是沒有任何值

22 = 2 * 10^1 + 2 : 22的前一個數字爲2

222 = 2*10^2 + 22 :222的前一個數字爲22

以此類推…

所以,在每次循環的時候,需要保存下,上一次結果的值,方便下一次計算

還需要使用到C庫當中使用的pow函數,來計算某個數的n次方,我們在該題目當中使用的是10的n次方,n隨着循環的次數,以此遞增。

代碼示例:

#include <stdio.h>
#include <math.h>

int main()
{
	//n爲a的個數
	int n;
	double a, prev_sum = 0.0, total_sum = 0.0;
	printf("請輸入a的值以及n的值: ");
	scanf("%lf %d", &a, &n);
	//循環n次求總和
	for (int i = 0; i < n; i++)
	{
		prev_sum += a * pow(10, i); 
		total_sum += prev_sum;
	}
	printf("總和爲:%lf\n", total_sum);
	return 0;
}

運行截圖:

求=a+aa+aaa+...+ 之值,其中a是一個數字,n表示a的位數,n由鍵盤輸入。例如:答案

6.求n=120n!\sum\limits_{n=1}^{20}n! (即求1!+2!+3!+4!+…+20!)。

答案解析:

該題需要從1循環到20,依次求出每一個數字階乘的結果。所以在代碼當中需要有兩個循環,大循環從1到20,保證1到20個數字都被循環到,小循環裏計算N階乘,累加求和。注意:對於20的階乘已經超出了int類型能過表示的數字範圍,所以在代碼當中使用double類型

代碼示例:

#include<stdio.h>

int main()
{
	double total_sum = 0;
	for(int i = 1; i <= 20; i++) 
	{
		double single_sum = 1;
		for (int j = i; j > 0; j--)
		{
			single_sum *= j;
		}
		total_sum += single_sum;
	}
	printf("1~20每個數字階乘總和爲:%lf\n",total_sum);
	return 0;
}

運行截圖:

求 (即求1!+2!+3!+4!+...+20!)。

7.k=1100k\sum\limits_{k=1}^{100}k +k=150k2\sum\limits_{k=1}^{50}{k}^2 +k=1101k\sum\limits_{k=1}^{10}{\frac{1}{k}}

答案解析:

對於k=1100k\sum\limits_{k=1}^{100}k而言,指的是求從1到100的和。每個數字爲整數,求和也爲整數

對於k=150k2\sum\limits_{k=1}^{50}{k}^2而言,指的是求從12到502的和。每個數字爲整數,求和也爲整數。

對於k=1101k\sum\limits_{k=1}^{10}{\frac{1}{k}}而言,指的是求從11\frac{1}{1}110\frac{1}{10}的和。每個數字不是整數,求和也不是整數。

綜上所述:求和結果不是整數,所以定義求和變量是需要定義爲帶有精度的變量double

該題目,最大的求和是從從1到100,所以需要一個循環,從1遍歷到100。針對第一種情況,則遍歷100次停下來。針對第二種情況,則遍歷50次的時候停下來,針對第三種情況,則遍歷10遍就停下來。

最後,在遍歷每一個數字的時候,針對三種不同的情況求和。最後將三種不同請求的和加起來就是總體的和

代碼示例:

#include <stdio.h>

int main()
{
	double total_sum = 0, sum1 = 0, sum2 = 0, sum3 = 0.0;
	for (int k = 1; k <= 100; k++)
	{
		sum1 += k;
		//遍歷50次就不在執行情況2
		if (k <= 50)
		{
			sum2 += k * k;
		}
		//遍歷10次就不在執行情況3
		if (k <= 10)
		{
			sum3 += 1.0 / k;
		}
	}
	total_sum = sum1 + sum2 + sum3;
	printf("三種情況求和結果爲:%lf\n", total_sum);
	return 0;
}

運行截圖:

8.輸出所有的“水仙花數”,所謂“水仙花數”是指一個3位數,其各位數字立方和等於該數本身。例如,153是水仙花數,因爲153=1*+5*+3。

答案解析:

從題目當中得到”水仙花數“爲一個3位數,則範圍確定爲[100, 999]。另外需要獲取該數字的百位數字,十位數字,個位數字相加起來等於該數本身,則我們需要使用到%除的方式,來獲取每一個位權的數字。

代碼示例:

#include <stdio.h>

int main()
{
	 //a表示百位數字,b表示十位數字,c表示各位數字
	int a, b, c;
	for (int i = 100; i <= 999; i++)
	{
		a = i / 100;
		b = (i / 10) % 10;
		c = i % 10;
		if (a * a * a + b * b * b + c * c * c == i)
		{
			printf("%d\n", i);
		}
	}
	return 0;
}

運行截圖:

9.一個數如果恰好等於它的因子之和,這個數就稱爲“完數”。例如,6的因子爲1,2,3,而6=1+2+3,因此6是“完數”。編程序找出1000之內的所有完數,並按下面格式輸出其因子:

6 its factors are 1,2,3

答案解析:

因子:整數a除以整數b(b≠0) 的商正好是整數而沒有餘數,我們就說b是a的因子。整數n除以m,結果是無餘數的整數,那麼我們稱m就是n的因子。 需要注意的是,唯有被除數,除數,商皆爲整數,餘數爲零時,此關係才成立。因子是不包括自身的

舉一個例子:20 = 4 * 5,則4和5就是20的因子,也被稱之爲因子

代碼示例:

#include<stdio.h>

int main()
{
	int data, fator, sum;      /* data表示要判斷的數,fator表示因子,sum表示因子之和*/

	for (data = 2; data <= 1000; data++)
	{
		//1是所有整數的因子,所以因子之和從1開始
		sum = 1;
		for (fator = 2; fator <= data / 2; fator++)
		{
			/* 判斷data能否被fator整除,能的話fator即爲因子  因子不包括自身 */
			if (data % fator == 0)
			{
				sum += fator;
			}
		}
		// 判斷此數是否等於因子之和 */
		if (sum == data)    
		{
			printf("%d its factors are 1, ", data);
			for (fator = 2; fator <= data / 2; fator++)
			{
				if (data % fator == 0)
				{
					printf("%d, ", fator);
				}
			}
			printf("\n");
		}
	}
	return 0;
}

運行截圖:

10.有一個分數序列,求出這個數列的前20項之和。

21\frac{2}{1}32\frac{3}{2}53\frac{5}{3}85\frac{8}{5}138\frac{13}{8}2513\frac{25}{13},…

答案解析:

從題目當中可以看出來,下一個分式當中的分子爲上一個分式中分子和分母的和,分母爲上一個分式的分子。通過這個規律不難推出下一個分式的分子和分母,需要注意的是,保存分式的結果不能使用到整數,因爲有可能會有小數的存在,所以我們需要選用浮點數double

代碼示例:

#include <stdio.h> 
//定義循環次數
#define COUNT 20

int main()
{
	//定義第一個分式的分子爲a, 值爲2; 定義分母爲b,值爲1
	//定義相加的和爲sum,初始值爲0
	double a = 2, b = 1, sum = 0;
	double temp;

	for (int i = 0; i < COUNT; i++)
	{
		sum += a / b;
		//記錄前一項分子
		temp = a;
		//前一項分子與分母之和爲後一項分子
		a = a + b;
		//前一項分子爲後一項分母
		b = temp;
	}
	printf("前%d項之和爲:sum=%9.7f\n", COUNT, sum);
	return 0;
}

運行截圖:

11.一個球從100m高度自由落下,每次落地後反彈回原高度的一半,再落下,再反彈。求它在第10次落地時共經過多少米,第10次反彈多高。

答案解析:

該題目需要循環10次,在每一循環的時候,需要將下落的高度和回彈的高度加起來。需要注意的點,第10次下落不需要在計算回彈的距離了,所以需要特殊處理下。在計算每次高度的時候,會有小數存在,所以需要選用浮點數

代碼示例:

#include <stdio.h>

int main()
{
	//總高度
	double total_m = 100.0;
	//小球經歷的米數
	double total_sum = 0.0;
	for (int i = 0; i < 10; i++)
	{
		total_sum += total_m;
		total_m /= 2;
		total_sum += total_m;
	}
	//不需要計算第10次的反彈高度,所以減去
	total_sum -= total_m;
	printf("小球總共經歷%lf米, 第10次反彈%lf米\n", total_sum, total_m);
	return 0;
}

運行截圖:

12.猴子喫桃問題。猴子第1天摘下若干個桃子,當即吃了一半,還不過癮,又多吃了一個。第2天早上又將剩下的桃子喫掉一半,又多吃了一個。以後每天早上都吃了前一天剩下的一半零一個。到第10天早上想再喫時,就只剩一個桃子了。求第1天共摘多少個桃子。

答案解析:

從題面上來看,可以推出,後一天的桃子數量 = 前一天桃子數量 / 2 - 1。所以,該公式也可以寫成前一天的桃子數量 = (後一天桃子數量+1) * 2。所以我們知道了第10天剩餘桃子的數量,則可以依次推算出桃子的前一天桃子的總數。需要注意的點,猴子只是吃了9天,所以,我們只需要遍歷9次就可以了。

代碼示例:

#include <stdio.h>

int main()
{
	int day = 9;
	int prev_day_count;
	int cur_day_count = 1;
	while (day > 0)
	{
		prev_day_count = (cur_day_count + 1) * 2;
		cur_day_count = prev_day_count;
		day--;
	}
	printf("total count : %d\n", cur_day_count);
	return 0;
}

運行截圖:

13.用迭代法求x=a\sqrt{a}。求平方根的迭代公式爲

xn+1x_{n+1} = 12\frac{1}{2}(xnx_{n} + axn\frac{a}{x_n})

要求前後兩次求出的x的差的絕對值小於10510^{-5}

答案解析:

題面上已經告訴兩條信息,一個是x=a\sqrt{a},所以我們可以通過a求出x的值。另外一條是xn+1x_{n+1} = 12\frac{1}{2}(xnx_{n} + axn\frac{a}{x_n}),可以通過x的值求出xn+1x_{n+1}的值,所以,只需要輪詢的計算,不斷的計算差值,直到滿足差值小於10510^{-5}就可以停止了

代碼示例:

#include <stdio.h>
#include <math.h>

int main()
{
	float a, x0, x1;
	printf("請輸入一個正數: ");
	scanf("%f", &a);
	x0 = a / 2;
	x1 = (x0 + a / x0) / 2;
	do
	{
		x0 = x1;
		x1 = (x0 + a / x0) / 2;
	} while (fabs(x0 - x1) >= 1e-5);
	printf("[%f] 的平方根爲 [%f]\n", a, x1);
	return 0;
}

運行截圖:

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

2x3x^3- 4x2x^2 + 3xx - 6= 0

答案解析:

牛頓迭代法的公式爲:

xn+1x_{n+1} = xnx_{n} - f(xn)f(xn)\frac{f(x_{n})}{f'(x_{n})}

其中,xnx_{n}爲輸出的值,在該題目當中爲1.5。f(xn)f(x_{n})爲公式2x3x^3- 4x2x^2 + 3xx - 6。f(xn)f'(x_{n})爲導數,根據導數原則:

規則1:xnx^n = n * x(n1)x^{(n-1)}, 規則2:常數的導數爲0。可以推導出f(xn)f'(x_{n}) = 6x2x^2 - 8x + 3。

在依照牛頓迭代法計算出xn+1x_{n+1}的值,直到求出的差值小於0.00001

代碼示例:

#include <stdio.h>
#include <math.h>

int  main()
{
	double x1, x0, f, f1;
	x1 = 1.5;
	do
	{
		x0 = x1;
		f = ((2 * x0 - 4) * x0 + 3) * x0 - 6;
		f1 = (6 * x0 - 8) * x0 + 3;
		x1 = x0 - f / f1;
	} while (fabs(x1 - x0) >= 1e-5);
	printf("方程在1.5附近的根爲:%lf\n", x1);
	return 0;
}

運行截圖:

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

2x3x^3- 4x2x^2 + 3xx - 6= 0

答案解析:

將區間劃分爲兩部分,記錄區間左右端點,得到中點。每次運算將中點帶入方程進行運算,求得結果,進行分析:

結果 > 0:將中位數賦值給右端點

結果 < 0:將中位數賦值給左端點

以此類推…

fabs函數是一個求絕對值的函數,求出x的絕對值,和數學上的概念相同;

le-5:10510^{-5},即0.00001

代碼示例:

#include<stdio.h>
#include<math.h>

int main()
{
	double left = -10, right = 10, mid;
	double temp = 10;
	while (fabs(temp) > 1e-5)
	{
		mid = (left + right) / 2;
		//((2x - 4)*x + 3) * x - 6 ==> 2x^3 - 4x^2 + 3x -6
		temp = ((2 * mid - 4) * mid + 3) * mid - 6;

		if (temp > 0)
		{
			right = mid;
		}
		else if (temp < 0)
		{
			left = mid;
		}
	}
	printf("在(-10,10)的根爲:%lf", mid);
	return 0;
}

運行截圖:

16.輸出以下圖案:

​ *

​ ***

*****

*******

*****

​ ***

​ *

答案解析:

該題目需要關心當前行對應的從最左邊到第一顆*的空格數量以及星星數量。將該題分爲兩個部分,前面4行和後面3行來進行拆分。

前4行中:

第一行:行號爲0, 空格數爲3,星星數量爲1;

第二行:行號爲1, 空格數爲2, 星星數量爲3;

第三行:行號爲2, 空格數爲1, 星星數量爲5;

第四行:行號爲3, 空格數爲0,星星數量爲7;

則我們可以推出兩組關係,即行號和空格數量關係爲:空格數 = 3 - 行號 。行號與星星的關係爲:星星數 = 2 * 行號 + 1

後三行中:

第一行:行號爲0,空格數爲1,星星數量爲5;

第二行:行號爲1, 空格數爲2, 星星數量爲3;

第三行:行號爲2, 空格數爲3,星星數量爲1;

則我們推出兩組關係,即行號與數量的關係:空格數 = 行號 + 1。行號與星星的關係:星星數 = 7 - 2 * (行號+1)

基於上面的關係,我們寫出如下代碼:

代碼示例:

#include <stdio.h>

int main()
{
	int cur_row, space_count, start_count;
	//輸出前4行內容
	for (cur_row = 0; cur_row < 4; cur_row++)
	{
		//計算當前行空格數量,並且進行打印
		for (space_count = 3 - cur_row; space_count > 0; space_count--)
		{
			printf(" ");
		}
		//計算當前行*數量,並且進行打印
		for (start_count = 2 * cur_row + 1; start_count > 0; start_count--)
		{
			printf("*");
		}
		printf("\n") ;
	}
	//輸出後三行
	for (cur_row = 0; cur_row < 3; cur_row++)
	{
		for (space_count = cur_row + 1; space_count > 0; space_count--)
		{
			printf(" ");
		}

		for (start_count = 7 - 2 * (cur_row + 1); start_count > 0; start_count--)
		{
			printf("*");
		}
		printf("\n");
	}
	return 0;
}

運行截圖:

17.兩個乒乓球隊進行比賽,各出3人。甲隊爲A,B,C 3人,乙隊爲X,Y,Z 3人。已抽籤決定比賽名單。有人向隊員打聽比賽的名單,A說他不和X比,C說他不和X,Z比,請編程序找出3對賽手的名單。

答案解析:

從題面上得知,每隊爲3人,則隱含條件爲隊內三人是不能比賽的,並且A一定不會和X比,C一定不會X和Z比;則我們不難寫出判斷條件:

如果A和X比 或者 C和X比 或者 C和Z比 或者 A和B比 或者 A和C比 或者 B和C比,都是不可以的;所以我們只要窮舉A比賽對象,B比賽對象,C比賽對象,判斷上述條件就可以了;

代碼示例:

#include <stdio.h>

int main()
{
	int A_battle, B_battle, C_battle;
	//如果A對戰的對象從“X”到“Z”
	for (A_battle = 'X'; A_battle <= 'Z'; A_battle++)
	{
		//如果B對戰的對象從“X”到“Z”
		for (B_battle = 'X'; B_battle <= 'Z'; B_battle++)
		{
			//如果C對戰的對象從“X”到“Z”
			for (C_battle = 'X'; C_battle <= 'Z'; C_battle++)
			{
				//去除限制條件
				if (A_battle == 'X' || C_battle == 'X' || C_battle == 'Z' || B_battle == A_battle || B_battle == C_battle || A_battle == C_battle)
				{
					continue;
				}
				printf("A對%c,B對%c,C對%c", A_battle, B_battle, C_battle);
			}
		}
	}
	return 0;
}

運行截圖:

c語言程序設計第五版課後答案譚浩強

c語言程序設計第五版課後答案譚浩強更多答案

c語言程序設計第五版課後答案譚浩強 第四章課後答案
c語言程序設計第五版課後答案譚浩強 第六章課後答案
](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWcyMDIwLmNuYmxvZ3MuY29tL2Jsb2cvMjA0ODE1NS8yMDIwMDYvMjA0ODE1NS0yMDIwMDYzMDExNTMyOTIzOS04MDY2MzM3NTcucG5n?x-oss-process=image/format,png)

8.輸出所有的“水仙花數”,所謂“水仙花數”是指一個3位數,其各位數字立方和等於該數本身。例如,153是水仙花數,因爲153=1*+5*+3。

答案解析:

從題目當中得到”水仙花數“爲一個3位數,則範圍確定爲[100, 999]。另外需要獲取該數字的百位數字,十位數字,個位數字相加起來等於該數本身,則我們需要使用到%除的方式,來獲取每一個位權的數字。

代碼示例:

#include <stdio.h>

int main()
{
	 //a表示百位數字,b表示十位數字,c表示各位數字
	int a, b, c;
	for (int i = 100; i <= 999; i++)
	{
		a = i / 100;
		b = (i / 10) % 10;
		c = i % 10;
		if (a * a * a + b * b * b + c * c * c == i)
		{
			printf("%d\n", i);
		}
	}
	return 0;
}

運行截圖:

9.一個數如果恰好等於它的因子之和,這個數就稱爲“完數”。例如,6的因子爲1,2,3,而6=1+2+3,因此6是“完數”。編程序找出1000之內的所有完數,並按下面格式輸出其因子:

6 its factors are 1,2,3

答案解析:

因子:整數a除以整數b(b≠0) 的商正好是整數而沒有餘數,我們就說b是a的因子。整數n除以m,結果是無餘數的整數,那麼我們稱m就是n的因子。 需要注意的是,唯有被除數,除數,商皆爲整數,餘數爲零時,此關係才成立。因子是不包括自身的

舉一個例子:20 = 4 * 5,則4和5就是20的因子,也被稱之爲因子

代碼示例:

#include<stdio.h>

int main()
{
	int data, fator, sum;      /* data表示要判斷的數,fator表示因子,sum表示因子之和*/

	for (data = 2; data <= 1000; data++)
	{
		//1是所有整數的因子,所以因子之和從1開始
		sum = 1;
		for (fator = 2; fator <= data / 2; fator++)
		{
			/* 判斷data能否被fator整除,能的話fator即爲因子  因子不包括自身 */
			if (data % fator == 0)
			{
				sum += fator;
			}
		}
		// 判斷此數是否等於因子之和 */
		if (sum == data)    
		{
			printf("%d its factors are 1, ", data);
			for (fator = 2; fator <= data / 2; fator++)
			{
				if (data % fator == 0)
				{
					printf("%d, ", fator);
				}
			}
			printf("\n");
		}
	}
	return 0;
}

運行截圖:

10.有一個分數序列,求出這個數列的前20項之和。

21\frac{2}{1}32\frac{3}{2}53\frac{5}{3}85\frac{8}{5}138\frac{13}{8}2513\frac{25}{13},…

答案解析:

從題目當中可以看出來,下一個分式當中的分子爲上一個分式中分子和分母的和,分母爲上一個分式的分子。通過這個規律不難推出下一個分式的分子和分母,需要注意的是,保存分式的結果不能使用到整數,因爲有可能會有小數的存在,所以我們需要選用浮點數double

代碼示例:

#include <stdio.h> 
//定義循環次數
#define COUNT 20

int main()
{
	//定義第一個分式的分子爲a, 值爲2; 定義分母爲b,值爲1
	//定義相加的和爲sum,初始值爲0
	double a = 2, b = 1, sum = 0;
	double temp;

	for (int i = 0; i < COUNT; i++)
	{
		sum += a / b;
		//記錄前一項分子
		temp = a;
		//前一項分子與分母之和爲後一項分子
		a = a + b;
		//前一項分子爲後一項分母
		b = temp;
	}
	printf("前%d項之和爲:sum=%9.7f\n", COUNT, sum);
	return 0;
}

運行截圖:

11.一個球從100m高度自由落下,每次落地後反彈回原高度的一半,再落下,再反彈。求它在第10次落地時共經過多少米,第10次反彈多高。

答案解析:

該題目需要循環10次,在每一循環的時候,需要將下落的高度和回彈的高度加起來。需要注意的點,第10次下落不需要在計算回彈的距離了,所以需要特殊處理下。在計算每次高度的時候,會有小數存在,所以需要選用浮點數

代碼示例:

#include <stdio.h>

int main()
{
	//總高度
	double total_m = 100.0;
	//小球經歷的米數
	double total_sum = 0.0;
	for (int i = 0; i < 10; i++)
	{
		total_sum += total_m;
		total_m /= 2;
		total_sum += total_m;
	}
	//不需要計算第10次的反彈高度,所以減去
	total_sum -= total_m;
	printf("小球總共經歷%lf米, 第10次反彈%lf米\n", total_sum, total_m);
	return 0;
}

運行截圖:

12.猴子喫桃問題。猴子第1天摘下若干個桃子,當即吃了一半,還不過癮,又多吃了一個。第2天早上又將剩下的桃子喫掉一半,又多吃了一個。以後每天早上都吃了前一天剩下的一半零一個。到第10天早上想再喫時,就只剩一個桃子了。求第1天共摘多少個桃子。

答案解析:

從題面上來看,可以推出,後一天的桃子數量 = 前一天桃子數量 / 2 - 1。所以,該公式也可以寫成前一天的桃子數量 = (後一天桃子數量+1) * 2。所以我們知道了第10天剩餘桃子的數量,則可以依次推算出桃子的前一天桃子的總數。需要注意的點,猴子只是吃了9天,所以,我們只需要遍歷9次就可以了。

代碼示例:

#include <stdio.h>

int main()
{
	int day = 9;
	int prev_day_count;
	int cur_day_count = 1;
	while (day > 0)
	{
		prev_day_count = (cur_day_count + 1) * 2;
		cur_day_count = prev_day_count;
		day--;
	}
	printf("total count : %d\n", cur_day_count);
	return 0;
}

運行截圖:

13.用迭代法求x=a\sqrt{a}。求平方根的迭代公式爲

xn+1x_{n+1} = 12\frac{1}{2}(xnx_{n} + axn\frac{a}{x_n})

要求前後兩次求出的x的差的絕對值小於10510^{-5}

答案解析:

題面上已經告訴兩條信息,一個是x=a\sqrt{a},所以我們可以通過a求出x的值。另外一條是xn+1x_{n+1} = 12\frac{1}{2}(xnx_{n} + axn\frac{a}{x_n}),可以通過x的值求出xn+1x_{n+1}的值,所以,只需要輪詢的計算,不斷的計算差值,直到滿足差值小於10510^{-5}就可以停止了

代碼示例:

#include <stdio.h>
#include <math.h>

int main()
{
	float a, x0, x1;
	printf("請輸入一個正數: ");
	scanf("%f", &a);
	x0 = a / 2;
	x1 = (x0 + a / x0) / 2;
	do
	{
		x0 = x1;
		x1 = (x0 + a / x0) / 2;
	} while (fabs(x0 - x1) >= 1e-5);
	printf("[%f] 的平方根爲 [%f]\n", a, x1);
	return 0;
}

運行截圖:

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

2x3x^3- 4x2x^2 + 3xx - 6= 0

答案解析:

牛頓迭代法的公式爲:

xn+1x_{n+1} = xnx_{n} - f(xn)f(xn)\frac{f(x_{n})}{f'(x_{n})}

其中,xnx_{n}爲輸出的值,在該題目當中爲1.5。f(xn)f(x_{n})爲公式2x3x^3- 4x2x^2 + 3xx - 6。f(xn)f'(x_{n})爲導數,根據導數原則:

規則1:xnx^n = n * x(n1)x^{(n-1)}, 規則2:常數的導數爲0。可以推導出f(xn)f'(x_{n}) = 6x2x^2 - 8x + 3。

在依照牛頓迭代法計算出xn+1x_{n+1}的值,直到求出的差值小於0.00001

代碼示例:

#include <stdio.h>
#include <math.h>

int  main()
{
	double x1, x0, f, f1;
	x1 = 1.5;
	do
	{
		x0 = x1;
		f = ((2 * x0 - 4) * x0 + 3) * x0 - 6;
		f1 = (6 * x0 - 8) * x0 + 3;
		x1 = x0 - f / f1;
	} while (fabs(x1 - x0) >= 1e-5);
	printf("方程在1.5附近的根爲:%lf\n", x1);
	return 0;
}

運行截圖:

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

2x3x^3- 4x2x^2 + 3xx - 6= 0

答案解析:

將區間劃分爲兩部分,記錄區間左右端點,得到中點。每次運算將中點帶入方程進行運算,求得結果,進行分析:

結果 > 0:將中位數賦值給右端點

結果 < 0:將中位數賦值給左端點

以此類推…

fabs函數是一個求絕對值的函數,求出x的絕對值,和數學上的概念相同;

le-5:10510^{-5},即0.00001

代碼示例:

#include<stdio.h>
#include<math.h>

int main()
{
	double left = -10, right = 10, mid;
	double temp = 10;
	while (fabs(temp) > 1e-5)
	{
		mid = (left + right) / 2;
		//((2x - 4)*x + 3) * x - 6 ==> 2x^3 - 4x^2 + 3x -6
		temp = ((2 * mid - 4) * mid + 3) * mid - 6;

		if (temp > 0)
		{
			right = mid;
		}
		else if (temp < 0)
		{
			left = mid;
		}
	}
	printf("在(-10,10)的根爲:%lf", mid);
	return 0;
}

運行截圖:

16.輸出以下圖案:

​ *

​ ***

*****

*******

*****

​ ***

​ *

答案解析:

該題目需要關心當前行對應的從最左邊到第一顆*的空格數量以及星星數量。將該題分爲兩個部分,前面4行和後面3行來進行拆分。

前4行中:

第一行:行號爲0, 空格數爲3,星星數量爲1;

第二行:行號爲1, 空格數爲2, 星星數量爲3;

第三行:行號爲2, 空格數爲1, 星星數量爲5;

第四行:行號爲3, 空格數爲0,星星數量爲7;

則我們可以推出兩組關係,即行號和空格數量關係爲:空格數 = 3 - 行號 。行號與星星的關係爲:星星數 = 2 * 行號 + 1

後三行中:

第一行:行號爲0,空格數爲1,星星數量爲5;

第二行:行號爲1, 空格數爲2, 星星數量爲3;

第三行:行號爲2, 空格數爲3,星星數量爲1;

則我們推出兩組關係,即行號與數量的關係:空格數 = 行號 + 1。行號與星星的關係:星星數 = 7 - 2 * (行號+1)

基於上面的關係,我們寫出如下代碼:

代碼示例:

#include <stdio.h>

int main()
{
	int cur_row, space_count, start_count;
	//輸出前4行內容
	for (cur_row = 0; cur_row < 4; cur_row++)
	{
		//計算當前行空格數量,並且進行打印
		for (space_count = 3 - cur_row; space_count > 0; space_count--)
		{
			printf(" ");
		}
		//計算當前行*數量,並且進行打印
		for (start_count = 2 * cur_row + 1; start_count > 0; start_count--)
		{
			printf("*");
		}
		printf("\n") ;
	}
	//輸出後三行
	for (cur_row = 0; cur_row < 3; cur_row++)
	{
		for (space_count = cur_row + 1; space_count > 0; space_count--)
		{
			printf(" ");
		}

		for (start_count = 7 - 2 * (cur_row + 1); start_count > 0; start_count--)
		{
			printf("*");
		}
		printf("\n");
	}
	return 0;
}

運行截圖:

17.兩個乒乓球隊進行比賽,各出3人。甲隊爲A,B,C 3人,乙隊爲X,Y,Z 3人。已抽籤決定比賽名單。有人向隊員打聽比賽的名單,A說他不和X比,C說他不和X,Z比,請編程序找出3對賽手的名單。

答案解析:

從題面上得知,每隊爲3人,則隱含條件爲隊內三人是不能比賽的,並且A一定不會和X比,C一定不會X和Z比;則我們不難寫出判斷條件:

如果A和X比 或者 C和X比 或者 C和Z比 或者 A和B比 或者 A和C比 或者 B和C比,都是不可以的;所以我們只要窮舉A比賽對象,B比賽對象,C比賽對象,判斷上述條件就可以了;

代碼示例:

#include <stdio.h>

int main()
{
	int A_battle, B_battle, C_battle;
	//如果A對戰的對象從“X”到“Z”
	for (A_battle = 'X'; A_battle <= 'Z'; A_battle++)
	{
		//如果B對戰的對象從“X”到“Z”
		for (B_battle = 'X'; B_battle <= 'Z'; B_battle++)
		{
			//如果C對戰的對象從“X”到“Z”
			for (C_battle = 'X'; C_battle <= 'Z'; C_battle++)
			{
				//去除限制條件
				if (A_battle == 'X' || C_battle == 'X' || C_battle == 'Z' || B_battle == A_battle || B_battle == C_battle || A_battle == C_battle)
				{
					continue;
				}
				printf("A對%c,B對%c,C對%c", A_battle, B_battle, C_battle);
			}
		}
	}
	return 0;
}

運行截圖:

c程序設計第五版課後答案譚浩強

c語言程序設計第五版課後答案譚浩強更多答案

c程序設計第五版課後答案譚浩強 第四章課後答案
c程序設計第五版課後答案譚浩強 第六章課後答案

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章