第五章
1.请画出例5.6中给出的3个程序段的流程图
流程图1:
流程图2:
流程图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;
}
运行截图:
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;
}
运行截图:
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;
}
运行截图:
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.求 S n S_n Sn=a+aa+aaa+…+ a a + ⋯ + a ⏞ n 个 a \overbrace{aa+\dots+a}^{n个a} aa+⋯+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;
}
运行截图:
6.求 ∑ n = 1 20 n ! \sum\limits_{n=1}^{20}n! n=1∑20n! (即求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;
}