关于c:浙大版C语言程序设计第四版何钦铭颜晖-第4章-循环结构-课后习题答案

2次阅读

共计 11729 个字符,预计需要花费 30 分钟才能阅读完成。

你也能够上程序咖(https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。

一、选择题

1. 以下程序段()不能实现求 s = 1+2+…+n-1。

A.

int i, n, s=0;
scanf("%d", &n);
for(i=1; i<n; i++){s=s+i;}

B.

int i,n,s=0;
scanf("%d",&n);
for(i=1; i<=n-1;++i){s=s+i;}

C.

int i,n, s≈0;
scanf("%d", &n);
for(i=n-1;i>0;i--){s=s+i;}

D.

int i,n,s=0;
scanf("%d",&n);
for(i=n-1;i>0;++i){s=s+i;}

答:D

解析:

选项 A、B、C 的代码都能够实现题目要求。然而选项 D 的代码执行起来是个死循环,i 的值从 n-1 开始,而后 ++i,循环的完结条件是 i>0,i 的值越加越大,始终大于 0,条件永远成立。实现的并不是从 1 累加到 n-1。

2. 输出 65 14 <Enter>,以下程序段的输入后果为()。

int m, n;
scanf("%d%d", &m,&n);
while(m!=n) {while(m>n)    m=m-n;
    while(n>m)    n=n-m;
}
printf("m=%d\n", m);

A. m=3
B. m=2
C. m=1
D. m=0

答:C

解析:

m 的初始值为 65,n 的初始值为 14。第一个 while 的条件 m!=n,是成立的。执行外面的循环体。

第二个 while 的条件 m >n,此时也是成立的,执行外面的循环体 m=m-n;执行后 m 的值为 51,因为是循环语句,要再次判断条件是否成立,m>n 仍然成立,再执行一次循环体 m=m-n;执行后 m 的值为 37。再次判断条件 m>n 仍然成立,再一次执行循环体 m=m-n;执行后 m 的值为 23。再次判断条件 m>n 仍然成立,再一次执行循环体 m=m-n;执行后 m 的值为 9。再次判断条件 m>n 不成立,完结这个循环。

程序继续执行到第三个 while 循环,条件是 n>m,此时 m 的值为 9,n 的值为 14,条件成立,执行外面的循环体 n=n-m,执行后 n 的值为 5。再来判断循环条件 n>m,曾经不成立了。完结这个循环。

此时外面的两个循环作为最外层的循环的循环体,完结这次执行之后,要再来判断最外层循环的条件 m!=n,此时 m 的值为 9,n 的值为 5。条件成立,要再次执行外面的循环体,就是两个里层循环。先看第二个循环条件 m>n,成立的,那吗执行外面的循环体 m=m-n,执行后 m 的值为 4,再来判断条件 m>n,曾经不成立了,完结这个循环。

程序继续执行到第三个循环,条件是 n>m,此时 m 的值为 4,n 的值为 5,条件成立,执行外面的循环体 n=n-m,执行后 n 的值为 1。再来判断循环条件 n>m,曾经不成立了。完结这个循环。

这两个循环执行完结后,要持续判断最外层的循环条件 m!=n,此时 m 的值为 4,n 的值为 1,条件成立,再次进去执行外面的两个内层循环。先来判断第二个循环条件 m>n,成立的,执行外面的循环体 m=m-n,执行后,m 的值为 3,再来判断条件 m>n,仍然成立,执行外面的循环体 m=m-n,执行后,m 的值为 2,再来判断条件 m>n,仍然成立,执行外面的循环体 m=m-n,执行后,m 的值为 1。再来判断条件 m>n,此时曾经不成立了。完结这个循环。

程序继续执行到第三个 while 循环,条件是 n >m,此时 m 的值为 1,n 的值也为 1。条件不成立,完结这个循环。

而后要再来判断外层循环的条件 m!=n,此时 m 的值为 1,n 的值也为 1。条件不成立,完结这个外层循环。

程序持续向下执行,打印输出语句,m 的值为 1。

3.C 语言中 while 和 do-while 循环的次要区别是()。

A. do-while 的循环体至多无条件执行一次

B. while 的循环管制条件比 do-while 的循环管制条件严格

C. do-while 容许从内部转到循环体内

D. do-while 的循环体不能是复合语句

答:A

解析:

while 循环是先判断条件,条件成立再执行循环体。

do-while 循环是先执行循环体,再判断条件是否成立。即便条件不成立,也曾经执行一次循环体了。

4. 下列叙述中正确的是()。

A. break 语句只能用于 switch 语句体中

B. continue 语句的作用是使程序的执行流程跳出蕴含它的所有循环

C. break 语句只能用在循环体内和 switch 语句体内

D. 在循环体内应用 break 语句和 continue 语句的作用雷同

答:C

解析:

break 语句能够应用在 switch 中。也能够应用在循环中,示意强制完结循环。

break 语句用在循环中示意强制完结循环,无论循环条件是否成立,循环都彻底的完结了。而 continue 语句,也是用于强制完结循环,但只是完结这一次循环,循环下次继续执行。

5. 下列叙述中正确的是()。

A. do-while 语句形成的循环不能用其余语句形成的循环来代替

B. do-while 语句形成的循环只能用 break 语句退出

C. 用 do-while 语句形成的循环,在 while 后的表达式为非零时完结循环

D. 用 do-while 语句形成的循环,在 while 后的表达式为零时完结循环

答:D

解析:

C 语言中的三种循环语句 for,while 和 do-while,其实是能够相互代替的,只是写法不同。有些状况应用 for 循环比拟不便,有些状况应用 while 比拟不便,有些时候应用 do-while 比拟不便。这三种循环的成立条件,都是非零,就会执行循环体。所以此题目的正确答案是选项 D。

6. 下列程序段的输入后果是()。

int i;
for(i=1; i<6; i++){if(i%2!=0){printf("#");
        continue;
  }
    printf("*");
}

A. #*#*#
B. #####
C. *****
D. *#*#*

答:A

解析:

此代码实现的是判断变量 i 的值,如果为奇数,打印 #,如果为偶数,打印 *

变量 i 的初始值为 1,循环条件为 i<6,成立外面的循环体,是一个 if 语句,持续判断 if 语句的条件,i%2!=0,也是成立的,打印一个 #,而后执行 continue 语句,完结本次循环,不打印 *

而后执行 i++,此时 i 的值为 2,循环条件仍然成立,判断 if 语句的条件,不成立,那么不执行 if 里的代码,跳过 if 语句执行前面的打印语句,打印出 *

而后执行 i++,此时 i 的值为 3,循环条件仍然成立,判断 if 语句的条件,成立的,执行 if 语句里的内容,打印 #,而后执行 continue,完结这次循环。

而后执行 i+=,此时 i 的值为 4,循环条件仍然成立,判断 if 语句的条件,不成立,那吗不执行 if 里的代码,跳过 if 语句执行前面的打印语句,打印出 *

而后执行 i++,此时 i 的值为 5,循环条件仍然成立,判断 if 语句的条件,成立的,执行 if 语句里的内容,打印 #,而后执行 continue,完结这次循环。

而后执行 i++,此时 i 的值为 6,循环条件不成立了,完结 for 循环。

二、填空题

1. 执行以下程序段后,变量 i 的值是(),s 的值是()。

int i, s=0;
for(i=1; i<=10: i=i+3)
    s=s+i;

答:13,22

解析:

变量 i 的初始值为 1,s 的初始值为 0。for 循环的条件是 i <= 10,

第一次循环:i 的值为 1,s 的值为 0,执行循环体的内容后,s 的值为 1。而后执行 i=i+3,而后 i 的值为 4。

第二次循环:i 的值为 4,s 的值为 1,执行循环体的内容后,s 的值为 5。而后执行 i=i+3,而后 i 的值为 7。

第三次循环:i 的值为 7,s 的值为 5,执行循环体的内容后,s 的值为 12。而后执行 i=i+3,而后 i 的值为 10。

第四次循环:i 的值为 10,s 的值为 12,执行循环体的内容后,s 的值为 22。而后执行 i=i+3,而后 i 的值为 13。

不再满足循环的条件了,循环完结。

2. 下列程序段的输入后果是()。

for(int i=14; i>1; i/=3)
    printf("%d#",i);

答:14#4#

解析:

变量 i 的初始值是 14,for 循环的条件是 i>1,

第一次循环:i 的值为 14,执行循环体的内容后,打印 14#。而后执行 i/=3,而后 i 的值为 4。

第二次循环:i 的值为 4,执行循环体的内容后,打印 4#。而后执行 i/=3,而后 i 的值为 1。

不再满足循环的条件了,循环完结。

3. 以下程序段 A 的输入后果是(),程序段 B 的输入后果是()。

程序段 A

int num=0,s1=0;
while(num<=2) {
  num++;
  s1=s1+num;
}    
printf("s1=%d\n", s1);

程序段 B

int num=0,s2=0;
while(num<=2) {
    s2=s2+num;
    num++;
}
printf("s2=%d\n",s2);

答:s1=6,s2=3

解析:

程序段 A:

变量 num 的初始值是 0,s1 的初始值也是 0,while 循环的条件是 num<=2,

第一次循环,num 的值为 0,执行 num++ 后,num 的值为 1,而后执行 s1=s1+num 后,s1 的值为 1,

第二次循环,num 的值为 1,执行 num++ 后,num 的值为 2,而后执行 s1=s1+num 后,s1 的值为 3,

第三次循环,num 的值为 2,执行 num++ 后,num 的值为 3,而后执行 s1=s1+num 后,s1 的值为 6,

再判断 while 循环的条件,不成立了,循环完结。

程序段 B:

变量 num 的初始值是 0,s2 的初始值也是 0,while 循环的条件是 num<=2,

第一次循环,num 的值为 0,执行 s2=s2+num 后,s2 的值为 0,执行 num++ 后,num 的值为 1,

第二次循环,num 的值为 1,执行 s2=s2+num 后,s2 的值为 1,执行 num++ 后,num 的值为 2,

第三次循环,num 的值为 2,执行 s2=s2+num 后,s2 的值为 3,执行 num++ 后,num 的值为 3,

再判断 while 循环的条件,不成立了,循环完结。

4. 求序列和。计算并输入 s=1+12+ 123+ 1234+12345 的值。请填空。

int i,s=0, t=0;
for(i=1; i<=5; i++){
  t=__________+i;
  s=s+t;
}
printf("s=%d\n", s);

答:t*10

解析:循环中 i 的值是从 1 到 5。只有让 t 的值别离为 1,12,123,1234,12345 即可。所以思考 t =?加 i。每次?的值就该是 0,10,120,1230,12340 即可。

5. 以下程序段 A 的输入后果是(),程序段 B 的输入后果是()。

程序段 A

int num=0;
while(num<6){
  num++;
  if(num==3) break;
  printf("%d#",num);
}

程序段 B

int num=0;
while(num<6) {
  num++;
  if(num==3) continue;
  printf("%d#",num);
}

答:1#2#,1#2#4#5#6#

解析:这两段代码考查的是 break 和 continue 的用法的区别。

break 执行后,会彻底的完结循环。所以 num 的值为 3,满足条件后,整个循环就完结了,哪怕循环条件仍然成立。打印到 num 的值为 2。

continue 执行后,完结这次循环,然而循环还是会持续。所以 num 的值为 3,满足条件后,只是完结了这次循环,所以打印的时候,只是跳过了 3,前面的持续。

6. 输出 82pay!<Enter>, 以下程序段的输入后果为()。

char ch;
int i;
for(i=1; i<=6; i++){ch=getchar(); 
  if(ch>='a' && ch<='z') ch=(ch+5-'a')%26+'a';
  else 1f(ch>='0' & ch<='9') ch=(ch+2-'0')%10+'0';
  putchar(ch);
}

答:04ufd!

解析:这段代码实现的是将输出的自负,如果是数字,后移 2 位。如果是字母,后移 5 位。其余字符原样输入。

输出 8,输入 0。输出 2,输入 4。

输出 p,输入 u。输出 a,输入 f。输出 y,输入 d。输出 !,输入还是!。

7. 浏览下列程序段并答复问题。

    int i, j, k = 0, m = 0;
    for (i = 0; i < 2; i++)
    {
        ; /* 第 3 行 */
        for (j = 0; j < 3; j++)
            k++;
        m++; /* 第 6 行 */
    }
    printf("k=%d, m=%d\n", k, m);

(1) 程序段的输入是()
(2) 将第 6 行改为 ”m=m+k;”,程序段的输入是()
(3) 将第 3 行改为 ”k=0;”, 将第 6 行改为 ”m=m+k;”,程序段的输入是()

答:(1) k=6 m=2 (2) k=6 m=9 (3) k=3 m=6

解析:

(1)

变量 i 的初始值为 0,外层循环条件 i < 2,

外层循环第一次:i = 0,

​ 内层循环 j 的初始值为 0,内层循环条件 j<3,

​ 内层循环第一次:j = 0,满足条件,执行 k++ 后,k 的值为 1。而后执行 j++,j 的值为 1。

​ 内层循环第二次:j = 1,满足条件,执行 k++ 后,k 的值为 2。而后执行 j++,j 的值为 2。

​ 内层循环第三次:j = 2,满足条件,执行 k++ 后,k 的值为 3。而后执行 j++,j 的值为 3。

​ 不满足条件,完结内层循环。

​ 持续向下执行,到 m++,执行后,m 的值为 1。

​ 而后执行 i++,i 的值为 1。

外层循环第二次:i = 1,

​ 内层循环 从新执行 1 次。j 的值从 0 到 3。k 的值累加到 6。而后完结内层循环。持续向下执行,到 m++,执行后,m 的值为 2。而后执行 i++,i 的值为 2。

外层循环也完结了。最终 k 的值为 6,m 的值为 2。

(2) (3) 的剖析同 (1) 一样。

8. 输入方阵。输出一个正整数 n(1≤n≤10),打印一个 n 行 n 列的方阵。当 n=4 时,输入如下方阵。请填空。

13    14    15    16
9        10    11    12
5        6        7        8
1        2        3        4
    int i, j, n;
    scanf("%d", &n);
    for (________; i >= 0; ________)
    {for (j = 1; j <= n; j++)
        {printf("%4d", ________);
        }
        printf("\n");
    }

答:i=n-1,i–,4*i+j

解析:无。

9. 输入等腰三角形。输出一个正整数 n(1≤n≤9),打印一个高度为 n 且由 “*” 组成的等腰三角形图案。当 n=3 时,输入如下等腰三角形图案。请填空。

    *
 ***
*****
    int i, j, n;
    scanf("%nd", &n);
    for (i = 1; i <= n; i++)
    {for (________;  ________; ________)
        {printf(" ");
        }
        for (________;  ________; ________)
        {printf("*");
        }
        ________;
    }

答:j=1;j<=n-i;j++ j=1;j<=2*i-1;j++ printf("\n")

解析:无

10. 程序输入整数的各位数字。输出一个非负整数,从高位开始逐位宰割并输入它的各位数字。例如例如,输出 9837,输入 9 8 3 7。请填空。

int digit, number, pow, t_number;
    scanf("%d", &number);
    t_number = number;
    pow = 1;
    while (________)
    {
        pow = pow * 10;
        t_number = t_number / 10;
    }
    while (pow >= 1)
    {
        digit = ________;
        number = ________;

        pow = pow / 10;
        printf("%d", digit);
    }
    printf("\n");

答:t_number/10!=0 number/pow number%pow

解析:这里先将接管到的 number 的值,复制一份到 t_number 中。

第一个循环中获取的 pow 是为了获取 number 的最大的权重(就是最高位的权重值)。比方 123,最高位是 1,在百位上,权重就是 100。

第二个循环中,digit 是为了获取每个位上的数字。

三、程序设计题

题目 1:求奇数和。输出一批正整数(以零或正数为完结标记),求其中的奇数和。试编写相应程序。

答:

答案代码:

#include <stdio.h>
int main()
{// 习题(4.3.1)
    /*
    求奇数和。输出一批正整数(以零或正数为完结标记),求其中的奇数和。试编写相应程序。*/
    int n, sum;
    printf("input n:\n");
    sum = 0;
    while (n > 0)
    {scanf("%d", &n);
        if (n > 0)
        {if (n % 2 != 0)
            {sum += n; // 累加奇数}
        }
    }
    printf("奇数和为:%d\n", sum);

    return 0;
}

运行后果:

题目 2:展开式求和。输出一个实数 x,计算并输入下式的和,直到最初一项的绝对值小于 0.000 01,计算结果保留 4 位小数。要求定义和调用函数 fact(n) 计算 n 的阶乘,能够调用 pow() 函数求幂。试编写相应程序。

$$
s=1+x+\frac{x^2}{2!}+\frac{x^3}{3!}+\frac{x^4}{4!}+…
$$

答:

答案代码:

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

double fact(int n);
int main()
{// 习题(4.3.2)
    /*
    展开式求和。输出一个实数 x,计算并输入下式的和,直到最初一项的绝对值小于 0.000 01,计算结果保留 4 位小数。要求定义和调用函数 fact(n) 计算 n 的阶乘,能够调用 pow() 函数求幂。*/
    int n;
    double eps, x, s, item;
    eps = 0.00001;
    printf("input x:");
    scanf("%lf", &x);
    s = 0;
    item = 1;
    n = 1;
    while (fabs(item) >= eps)
    {
        s += item;
        item = pow(x, n) / fact(n);
        n++;
    }
    s = s + item;
    printf("后果为:%.4lf\n", s);

    return 0;
}

double fact(int n)
{
    int i;
    double result = 1;
    for (i = 1; i <= n; i++)
    {result *= i;}
    return result;
}

运行后果:

题目 3:求序列和。输出一个正整数 n,输入 2/1+3/2+5/3+8/5+… 的前 n 项之和,保留 2 位小数。该序列从第 2 项起,每项的分子是前一项分子与分母的和,分母是前项的分子。试编写相应程序。

答:

答案代码:

#include <stdio.h>

int main()
{// 习题(4.3.3)
    /*
    求序列和。输出一个正整数 n,输入 2/1+3/2+5/3+8/5+... 的前 n 项之和,保留 2 位小数。该序列从第 2 项起,每项的分子是前一项分子与分母的和,分母是前项的分子。*/
    int n, i, x, x1, x2;
    double sum;
    printf("input n:");
    scanf("%d", &n);
    x1 = 1;         // 分母
    x2 = 2;         // 分子
    x = x1 + x2; // 长期变量,求分子加分母,为筹备下次的分子。sum = (double)x2 / x1;
    x1 = x2;
    for (i = 1; i < n; i++)
    {
        x2 = x;
        sum += (double)x / x1;
        x = x1 + x;
        x1 = x2;
    }
    printf("sum = %.2lf\n", sum);

    return 0;
}

运行后果:

题目 4:和求序列和。输出两个正整数 a 和 n,求 a+aa+aaa+aa…a (n 个 a) 之和。例如,输出 2 和 3,输入 246 (2+22+222)。试编写相应程序。

答:

答案代码:

#include <stdio.h>

int main()
{// 习题(4.3.4)
    /*
    和求序列和。输出两个正整数 a 和 n,求 a+aa+aaa+aa...a (n 个 a) 之和。例如,输出 2 和 3,输入 246 (2+22+222)。*/
    int n, a, i, sum = 0, result = 0;
    printf("input a,n:");
    scanf("%d%d", &a, &n);
    for (i = 1; i <= n; i++)
    {
        sum += a;
        result += sum;
        a = a * 10;
    }
    printf("result= %d\n", result);

    return 0;
}

运行后果:

题目 5:换硬币。将笔零钱(大于 8 分,小于 1 元,准确到分) 换成 5 分,2 分和 1 分的硬币,每种硬币至多有一枚。输出金额,间有几种换法? 针对每种换法,输入各种面额硬币的数量和硬币的总数量。试编写相应程序。

答:

答案代码:

#include <stdio.h>

int main()
{// 习题(4.3.5)
    /*
    换硬币。将笔零钱(大于 8 分,小于 1 元,准确到分) 换成 5 分,2 分和 1 分的硬币,每种硬币至多有一枚。输出金额,间有几种换法? 针对每种换法,输入各种面额硬币的数量和硬币的总数量。*/

    int m, n1, n2, n5, total = 0, count = 0;
    printf("input m:");
    scanf("%d", &m);
    if (m <= 8 || m >= 10)
    {printf("Invalid!\n");
    }
    else
    {for (n5 = 1; n5 <= m; n5++)
        {for (n2 = 1; n2 <= m; n2++)
            {for (n1 = 1; n1 <= m; n1++)
                {if (n5 * 5 + n2 * 2 + n1 == m)
                    {
                        count++;
                        printf("5 分有 %d 个,2 分有 %d 个,1 分有 %d 个, 总共有 %d 个 \n", n5, n2, n1, n5 + n2 + n1);
                    }
                }
            }
        }
        printf("共有 %d 种算法 \n", count);
    }
    return 0;
}

运行后果:

题目 6:输入水仙花数。输出一个正整数 n (3≤n≤7),输入所有的 n 位水仙花数。水仙花数是指一个 n 位正整数,它的各位数字的 n 次幕之和等于它自身。例如 153 的各位数字的立方和是 1 3+53+33 =153。试编写相应程序。

答:

答案代码:

#include <stdio.h>
#include <math.h>
int main()
{// 习题(4.3.6)
    /*
    输入水仙花数。输出一个正整数 n (3≤n≤7),输入所有的 n 位水仙花数。水仙花数是指一个 n 位正整数,它的各位数字的 n 次幕之和等于它自身。例如 153 的各位数字的立方和是 1^3+5^3+3^3 =153。*/

    int n;
    do
    {printf("input n (3≤n≤7):");
        scanf("%d", &n);

    } while (n > 7 || n < 3);

    printf("水仙花数有:\n");

    int i = pow(10, n) - 1;
    int limit = 100;
    int digit, sum, s, m;

    while (i > 100) // 100-1000
    {
        sum = 0;
        s = i; // 153
        m = n;

        // 循环获取每个位上的数字
        while (s != 0)
        {digit = s / (int)(pow(10, m - 1));
            s %= (int)(pow(10, m - 1));
            sum += pow(digit, 3); // 每个位上的数字的立方和
            m--;
        }
        if (sum == i)
        {printf("%d\t", i);
        }

        i--;
    }

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

运行后果:

这里阐明一下,实际上水仙花数都是指 3 位数,然而此题目要求 3-7 位之间,所以我写答案就没有依照传统的那种求 3 位水仙花数的写法。

题目 7:求最大公约数和最小公倍数。输出两个正整数 m 和 n (m≤1000,n≤1000),求其最大公约数和最小公倍数。试编写相应程序。

答:

答案代码:

#include <stdio.h>

int main()
{// 习题(4.3.7)
    /*
    求最大公约数和最小公倍数。输出两个正整数 m 和 n (m≤1000,n≤1000),求其最大公约数和最小公倍数。*/

    int m, n, i, j;
    printf("input m,n:");
    scanf("%d%d", &m, &n);
    if (m <= 0 || n <= 0 || m > 1000 || n > 1000)
    {printf("Invalid!\n");
    }
    for (i = m < n ? m : n; i >= 1; i--)
    {if (m % i == 0 && n % i == 0)
        {printf("gcd = %d\n", i); // 最大公约数
            break;
        }
    }
    j = m / i * n;
    printf("lcm = %d\n", j); // 最小公倍数

    return 0;
}

运行后果:

题目 8:低空坠球。皮球从 heigh (来)高度自在落下,触地后反弹到原高度的一半,再落下,再反弹 … 如此重复。问皮球在第 n 次落地时,在地面一共通过多少间隔? 第 n 次反弹的高度是多少 ? 输入保留 1 位小数。试编写相应程序。

答:

答案代码:

#include <stdio.h>
#include <math.h>
int main()
{// 习题(4.3.8)
    /*
    低空坠球。皮球从 heigh (来)高度自在落下,触地后反弹到原高度的一半,再落下,再反弹... 如此重复。问皮球在第 n 次落地时,在地面一共通过多少间隔?  第 n 次反弹的高度是多少 ? 输入保留 1 位小数。*/

    int i, n;
    double h, s, x;
    printf("input h,n:");
    scanf("%lf%d", &h, &n);
    s = h;
    for (i = 1; i <= n; i++)
    {x = (double)h / pow(2, n);
        s += 2 * x;
    }
    printf("皮球从 %.1lf 米高度自在落下, 第 %d 次落地, 在地面共通过 %.1lf 米。第 %d 次反弹高度为 %.1lf 米 \n", h, n, s, n, x);

    return 0;
}

运行后果:

题目 9:打印菱形星号 "*" 图案。输出一个正整数 n (n 为奇数),打印一个高度为 n 的 "*" 菱形图案。例如,当 n 为 7 时,打印出以下图案。试编写相应程序。

      *
    * * *
  * * * * *
* * * * * * *
  * * * * *
    * * *
      *

答:

答案代码:

#include <stdio.h>
#include <math.h>
int main()
{// 习题(4.3.9)
    /*
    打印菱形星号 "*"  图案。输出一个正整数 n (n 为奇数),打印一个高度为 n 的 "*" 菱形图案。例如,当 n 为 7 时,打印出以下图案。*/

    int i, j, n, k;
    printf("input odd number n:");
    scanf("%d", &n);
    k = (n + 1) / 2; // 计算菱形的边长
    // 上三角
    for (i = 1; i <= k; i++)
    {for (j = 1; j <= n - 2 * i + 1; j++) // 循环打印空格
        {printf(" ");
        }
        for (j = 1; j <= 2 * i - 1; j++)
        {printf("*"); // 循环打印 *
        }
        printf("\n");
    }
    // 下三角
    for (i = n - k; i >= 1; i--)
    {for (j = 1; j <= n - (2 * i - 1); j++) // 打印空格
        {printf(" ");
        }
        for (j = 1; j <= 2 * i - 1; j++)
        {printf("*");
        }
        printf("\n");
    }
    return 0;
}

运行后果:

题目 10:猴子吃桃问题。一只猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个; 第二天早上又将剩下的桃子吃掉一半,又多吃了一个。当前每天早上都吃了前一天剩下的一半加一个。到第 n 天早上想再吃时,只剩下一个桃子了。问:第一天共摘了多少个桃子? 试编写相应程序。(提醒:采取逆向思维的办法,从后往前推断)

答:

答案代码:

#include <stdio.h>
int main()
{// 习题(4.3.10)
    /*
    猴子吃桃问题。一只猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个;
    第二天早上又将剩下的桃子吃掉一半,又多吃了一个。当前每天早上都吃了前一天剩下的一半加一个。到第 n 天早上想再吃时,只剩下一个桃子了。问:第一天共摘了多少个桃子?
    */

    int i, n, j, sum = 0;
    printf("input n:");
    scanf("%d", &n);
    j = 1; // j 为第 n 天的个数,也是第 n - 1 天吃剩下的个数
    for (i = 1; i < n; i++)
    {                             // 循环 n 天
        sum = sum + (j + 1) * 2; // 前一天的桃子数(第一天的)=(吃剩下的(第 2 天的桃子数)+1)*2
    }
    sum = sum + 1; // 加上最初一天的 1 个
    printf("第一天摘桃 %d 个 \n", sum);

    return 0;
}

运行后果:

题目 11:兔子繁殖问题。一对兔子,从出世后第 3 个月起每个月都生一对兔子。小兔子长到第 3 个月后每个月又生一对兔子。如果兔子都不死,请问第 1 个月出世的一对兔子,至多须要繁衔到第几个月时兔子总数才能够达到 n 对? 输出一个不超过 10 000 的正整数 n,输入兔子总数达到 n 起码须要的月数。试编写相应程序。

答:

答案代码:

#include <stdio.h>
int main()
{// 习题(4.3.11)
    /*
    兔子繁殖问题。一对兔子,从出世后第 3 个月起每个月都生一对兔子。小兔子长到第 3 个月后每个月又生一对兔子。如果兔子都不死,请问第 1 个月出世的一对兔子,至多须要繁衔到第几个月时兔子总数才能够达到 n 对?
    输出一个不超过 10 000 的正整数 n,输入兔子总数达到 n 起码须要的月数。*/

    int n, m, c;
    int f1 = 1, f2 = 1;
    printf("input n (n<=10000):");
    scanf("%d", &n);
    if (n < 2)
    {printf("想要 %d 对兔子, 至多 1 个月, 能够产出 1 对兔子 \n", n);
    }
    else
    {
        m = 2; // 月份
        c = 0; // 以后月的兔子数
        while (c < n)
        {
            c = f1 + f2;
            f1 = f2;
            f2 = c;
            m++;
        }
        printf("想要 %d 对兔子, 至多 %d 个月, 能够产出 %d 对兔子 \n", n, m, c);
    }

    return 0;
}

运行后果:

正文完
 0