《C程序设计教程(第四版)——谭浩强》
题目:
例题4.7 兔子的繁殖。这是一个有趣的古典问题:有一对兔子,从出生后的第3个月开始起每个月都生一对兔子。小兔子长到第3个月又生一对兔子。假设所有兔子都不死,问每个月的兔子总数为多少?
编程序求出前40个月的兔子数。
题目分析:
思想:
像这种有数据每到某一个时间段循环变化的数据,脑子里可以自动给他划上“幼年”“青年”“中年”“老年”“暮年”……这样的标签,这样会更加容易理解。
下面将以这个题目为例子来帮你理解这种思想:
月份 | 小兔子 | 中兔子 | 老兔子 | 兔子总对数 |
---|---|---|---|---|
1 | 1 | 0 | 0 | 1 |
2 | 0 | 1 | 0 | 1 |
3 | 1 | 0 | 1 | 2 |
4 | 1 | 1 | 1 | 3 |
5 | 2 | 1 | 2 | 5 |
6 | 3 | 2 | 3 | 8 |
…… | ||||
40 |
规律:
可以看到,后一个的兔子对总数等于前两个兔子总对数的和。即
x3=x1+x2
代码:
//《C程序设计教程(第四版)——谭浩强》
//例题4.7 兔子的繁殖。这是一个有趣的古典问题:有一对兔子,从出生后的第3个月开始起每个月都生一对兔子。
// 小兔子长到第3个月又生一对兔子。假设所有兔子都不死,问每个月的兔子总数为多少?
// 编程序求出前40个月的兔子数。
#include <stdio.h>
int main()
{
int x1=1;//有一对兔子
int x2=1;
int x3=0;
printf("第1个月的兔子对数%d\n",x1);
printf("第2个月的兔子对数%d\n",x2);
int i=3;//月份
while(i<=40)
{
x3=x1+x2;
// printf("第%d个月的兔子对数%d\n",i,x3);
x1=x2;
x2=x3;
i++;
// x2=x3;
// x1=x2;
// x3=x1+x2;
}
printf("第40个月的兔子对数:%d\n",x3);
return 0;
}
运行结果:
编写代码时遇见的问题:
1.不需要在额外创建一个变量sum来存放兔子的总对数
x3就是兔子的总对数,不需要在额外创建一个变量sum来存放兔子的总对数。
2.不要创建数组来存放兔子的对数
通过创建数组来存放兔子的对数,这样写虽然也可以,但是在逻辑上理解起来更复杂一点点,没有通过直接创建数写起来更加简洁简单。
3.C语言中int类型的变量一直增加问什么最后无论怎么变值都为-2?
在C语言中,当int类型的变量值增加到超出其能表示的最大值时,它会回绕(wrap around)到最小值,即-2147483648。
这是因为int类型在计算机内部使用补码形式表示,当数值增加到int类型的最大值2147483647后,如果继续增加,就会发生溢出,导致数值回绕到最小值-2147483648。这种现象通常被称为整数溢出(integer overflow)。
在计算机系统中,int类型一般采用补码表示法。补码是一种用于表示有符号整数的计算机中常用的编码方式。对于正数,补码就是其二进制表示;对于负数,补码是其绝对值的二进制表示取反后加1得到的。当int类型的变量值增加到一个非常大的数时,如果这个数超过了int类型能表示的最大范围(-2147483648到2147483647),就会发生溢出。此时,数值会回绕到int类型的最小值,即-2147483648。这是因为计算机内部存储和计算是基于二进制进行的,而二进制数的特性决定了当数值达到某个极限时,它会回绕到另一个极限值。
为了避免这种情况,可以使用更大范围的数据类型,如long long int,或者在编程时仔细管理数值的大小和范围,以防止溢出导致的错误结果
4.调试代码:
调试过程
调试代码小技巧:
可以在一些代码的关键位置插入一些输出数据,这样可以更加清楚直观的看到数据的变化规律,以便于更加清楚的掌握数据的变化