C程序设计 谭浩强 第五章

5循环结构

太简单 略

请添加图片描述

习题

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

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

π 4 ≈ 1 − 1 3 + 1 5 − 1 7 + ⋯ \frac{\pi}{4} \approx 1-\frac 13 + \frac 15-\frac 17+\cdots 4π131+5171+

用以上公式求 π \pi π的近似值,直到发现某一项的绝对值小于 1 0 − 6 10^{-6} 106为止(该项不累加)。

#include<stdio.h>
#include<math.h>
int main()
{
    int sign = 1;
    double pi = 0.0, n = 1, term = 1.0;
    
    while(fabs(term) >= le-6) {
        pi = pi + term;
        n = n + 2;
        sign = -sign;
        term = sign / n;
    }
    
    pi = pi + 4;
    
    return 0;
}
#include<stdio.h>
#include<math.h>

int main()
{
	int sign = 1;
	double pi = 0.0, n = 1, term = 1.0;
	
	int countE6 = 0, countE8 = 0;
	
	while(fabs(term) >= 1e-6) {
		pi = pi + term;
		n = n + 2;
		sign = -sign;
		term = sign / n;
		countE6++;
	}
	
	while(fabs(term) >= 1e-8) {
		pi = pi + term;
		n = n + 2;
		sign = -sign;
		term = sign / n;
		countE8++;
	}
	
	pi = pi + 4;
	
	printf("-6:%d -8:%d\n", countE6, countE8);
	
	return 0;
}

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

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

int main()
{
	int maxGongyueshu(int,int);
	int minGongbeishu(int,int,int);
	
	int a, b;
	scanf("%d%d", &a, &b);
	
	int max = maxGongyueshu(a,b);
	int min = minGongbeishu(a,b,max);
	
	printf("最大公约数为:%d,最小公倍数为:%d\n", max, min);
	
	return 0;
}

int maxGongyueshu(int a,int b) {
	
	int c = a % b;
	if(c != 0)	return maxGongyueshu(b,c);
	
	return b;
}

int minGongbeishu(int a,int b,int max) {
	
	return (a * b) / max;
	
}

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

#include<stdio.h>
#include<string.h>
#include<ctype.h>

int main()
{
	char str[100];
	int enWord, space, num, others, len, i;
	enWord = 0, space = 0, num = 0, others = 0;
	
	gets(str);
	len = (int) strlen(str);
	
	for(i = 0; i < len; i++) {
		if(isalpha(str[i])) enWord++;
		else if(isdigit(str[i])) num++;
		else if(str[i] == ' ') space++;
		else others++;
	}
	
	printf("英文字母的个数:%d, 空格的个数:%d, 数字的个数:%d, 其他字符的个数:%d\n", enWord, space, num, others);
	
	return 0;
}

5.求 S n = a + a a + a a a + ⋯ + a a ⋯ a S_n = a+aa+aaa+\cdots+aa\cdots a Sn=a+aa+aaa++aaa之值,其中a是一个数字,n表示a的位数,n由键盘输入。例如:

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

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

int main()
{
	int i, n, sum, t, a;
	int beiShu10 = 10;
	
	scanf("%d", &a);
	scanf("%d", &n);
	
	sum = a;
	int preNum = a;
	for(i = 1; i < n; i++) {
		t = a *pow(beiShu10,i) + preNum;
		preNum = t;
		sum += t;
	}
	
	printf("%d\n", sum\);
	
	
	return 0;
}

6.求

∑ n = 1 20 n ! ( 即 求 1 ! + 2 ! + 3 ! + 4 ! + ⋯ + 20 ! ) \sum_{n=1}^{20}n!(即求1!+2!+3!+4!+\cdots+20!) n=120n!(1!+2!+3!+4!++20!)

#include<stdio.h>

int main()
{
	long long myfactorial(int n);
	
	int i;
	long long sum;
	sum = 0;
	
	for(i = 1; i <= 20; i++) {
		sum += myfactorial(i);
	}
	
	printf("%lld\n", sum);
	
	return 0;
}

long long myfactorial(int n) {
	if( n == 1) {
		return 1;
	}
	
	return n * myfactorial(n-1);
}

7.求

∑ k = 1 100 k + ∑ k = 1 50 k 2 + ∑ k = 1 10 1 k \sum_{k=1}^{100}k+\sum_{k=1}^{50}k^2+\sum_{k=1}^{10} \frac{1}{k} k=1100k+k=150k2+k=110k1

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

int main()
{
	int sum1, sum2;
	float sum3;
	int i;
	sum1 = 0; sum2 = 0; sum3 = 0;
	
	for(i = 1; i <= 100; i++) {
		if(i >= 1 && i <= 50) {
			sum2 += pow(i,2);
		}
		
		if(i >= 1 && i <= 10) {
			sum3 += 1.0 / i;
		}
		
		sum1 += i;
	}
	
	printf("%f\n", sum1+sum2+sum3);
	
	return 0;
}

8.输出所有的“水仙花数”,所谓“水仙花数”是指一个3位数,其各位数字立方和等于该数本身。例如,153是水仙花数,因为 153 = 1 3 + 5 3 + 3 3 153 = 1^3+5^3+3^3 153=13+53+33

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

int main()
{
	//判断输入的数是3位数
	//百位的三次方 + 十位的三次方 + 个位的三次方 = 输入的数 ②
		//如果②成立,则输出是水仙花数
		//如果②不成立,则该数不是水仙花数
		
	int n;
	scanf("%d", &n);
	while(!(n / 100 >=1 && n / 100 <= 9)) {
		printf("请输入一个三位数\n");
		scanf("%d", &n);
	}
	
	int bai, shi, ge;
	bai = n / 100;
	shi = (n % 100) / 10;
	ge = n % 10;
	
	printf("每位数:%d %d %d\n", bai, shi, ge);
	
	int sum = 0;
	sum = pow(bai,3) + pow(shi,3) + pow(ge,3);
	
	if(sum == n)	printf("%d是水仙花数\n", n);
	else printf("%d不是水仙花数\n", n);
	
	return 0;
}

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

6 its factors are 1,2,3

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

int main()
{
	//外层循环1-1000
		//内层1:判断出i的所有因子,并存入数组①中
		//内层2:遍历数组①中的所有数,如果所有因子的和等于该数,则是完数
	
	int i, j;
	for(i = 1; i <= 1000; i++) {
		int arr[100], k = 0;
		for(j = 1; j < i; j++) {
			if(i % j == 0) {
				arr[k++] = j;
			}
		}
		
		int sum = 0;
		for(j = 0; j < k; j++) {
			sum += arr[j];
		}
		
		if(sum == i) {
			printf("%d its factors are ", i);
			for(j = 0; j < k; j++) {
				printf("%d ", arr[j]);
			}
			printf("\n");
		} 
	}
	
	return 0;
}

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

2 1 , 3 2 , 5 3 , 8 5 , 13 8 , 21 13 , ⋯ \frac{2}{1},\frac{3}{2},\frac{5}{3},\frac{8}{5},\frac{13}{8},\frac{21}{13},\cdots 12,23,35,58,813,1321,

#include<stdio.h>

int main()
{
	int preDenominator,preMolecule;
	float sum = 2/1;
	
	int i;
	preDenominator = 1;
	preMolecule = 2;
	for(i = 1; i < 20; i++) {
		sum += 1.0 *(preDenominator + preMolecule) / preMolecule;
		float tm = preDenominator + preMolecule;
		float td = preMolecule;
		preMolecule = tm;
		preDenominator = td;
	}
	
	printf("%f\n", sum);
	
	return 0;
}

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

#include<stdio.h>

int main()
{
	//h的初始值表示第一次触地弹跳的高度
	//s表示球路过的总长
	float h = 50, s = 100;
	int i;
	for(i = 2; i <= 10; i++) {
		s += h*2;
		h = h/2;
	}
	
	printf("共经历了%f米\n", s);
	printf("第10次反弹的高度为%f\n", h);
	
	return 0;
}

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

#include<stdio.h>

int main()
{
	//h的初始值表示第一次触地弹跳的高度
	//s表示球路过的总长
	float h = 50, s = 100;
	int i;
	for(i = 2; i <= 10; i++) {
		s += h*2;
		h = h/2;
	}
	
	printf("共经历了%f米\n", s);
	printf("第10次反弹的高度为%f\n", h);
	
	return 0;
}

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

x n + 1 = 1 2 ( x n + a x n ) x_{n+1} = \frac{1}{2}(x_{n}+\frac{a}{x_n}) xn+1=21(xn+xna)

要求前后两次求出的x的差的绝对值小于 1 0 − 5 10^{-5} 105

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

int main()
{
	printf("用迭代法求平方根\n");
	int a;
	scanf("%d", &a);
	float xn, xn1;
	xn = a;
	xn1 = (xn + a/xn) / 2;
	while(fabs(xn1 - xn)>=1e-5) {
		xn = xn1;
		xn1 = (xn + a/xn) / 2;
	}
	
	printf("%f\n", xn1);
	
	return 0;
}

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

2 x 3 − 4 x 2 + 3 x − 6 = 0 2x^3-4x^2+3x-6=0 2x34x2+3x6=0

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

int main()
{
	printf("求牛顿迭代法\n");
	float xn, xn1;
	xn = 1.5;
	float fxn_ = 6*pow(xn,2) - 8*xn + 3;
	float fxn = 2*pow(xn,3) - 4*pow(xn,2) + 3*xn -6;
	xn1 = xn - fxn / fxn_;
	
	while(fabs(xn1-xn) >= 1e-5) {
		xn = xn1;
		fxn_ = 6*pow(xn,2) - 8*xn + 3;
		fxn = 2*pow(xn,3) - 4*pow(xn,2) + 3*xn -6;
		xn1 = xn - fxn / fxn_;
	}
	
	printf("%f\n", xn1);
	
	return 0;
}

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

2 x 3 − 4 x 2 + 3 x − 6 = 0 2x^3-4x^2+3x-6=0 2x34x2+3x6=0

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

int main()
{
	float low, high, mid;
	low = -10; high = 10;
	mid = (low + high) / 2;
	float r;
	r = 2*pow(mid,3) - 4*pow(mid,2) + 3*mid - 6;
	
	while(fabs(r) >= 1e-5) {
		if(r > 0) {
			high = mid;
		}
		if(r < 0) {
			low = mid;
		}
		mid = (low + high) / 2;
		r = 2*pow(mid,3) - 4*pow(mid,2) + 3*mid - 6;
	}
	
	printf("%f\n", mid);
	
	return 0;
}

16.输出以下图案

  *

 ***

*****

*******

*****

 ***

  *
#include <stdio.h>

int main()
{
	int i, space, stars;
	for (i = 0; i < 4; i++)	{
		for (space = 3 - i; space > 0; space--) {
			printf(" ");
		}
		
		for (stars = 2 * i + 1; stars > 0; stars--) {
			printf("*");
		}
		printf("\n") ;
	}
	
	for (i = 0; i < 3; i++) {
		for (space = i + 1; space > 0; space--) {
			printf(" ");
		}
		
		for (stars = 7 - 2 * (i + 1); stars > 0; stars--) {
			printf("*");
		}
		printf("\n");
	}
	
	return 0;
}

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

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

int main()
{
	int A,B,C;
	
	for(A = 'X'; A <= 'Z'; A++) {
		for(B = 'X'; B <= 'Z'; B++) {
			for(C = 'X'; C <= 'Z'; C++) {
				if(A == 'X' || C == 'X' || C == 'Z' || A == B || A == C || B == C)	continue;
				printf("A对%c\nB对%c\nC对%c\n", A, B, C);
			}
		}
	}
	
	return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值