我试图制作一个包含C语言中斐波那契数的数组,但遇到了麻烦。我无法获取所有元素,并且某些元素的计算错误,而且我不知道我要去哪里。
#include <stdio.h>
int main(void){
int serie[]={1,1},sum=0,size=2;
while(size<=4000000){
serie[size]=serie[size-1]+serie[size-2];
printf("%d\n",serie[size-1]);
size+=1;
}
return 0;
}
输出:
1
2
4
6
11
17
28
45
73
118
191
309
500
809
1309
2118
3427
5545
8972
14517
23489
38006
61495
99501
160996
260497
421493
681990
1103483
1785473
2888956
4674429
7563385
12237814
19801199
32039013
51840212
83879225
135719437
219598662
355318099
574916761
930234860
1505151621
-1859580815
-354429194
2080957287
1726528093
-487481916
1239046177
751564261
1990610438
-1552792597
437817841
-1114974756
-677156915
-1792131671
1825678710
33547039
1859225749
1892772788
-542968759
1349804029
806835270
-2138327997
-1331492727
825146572
-506346155
318800417
-187545738
131254679
-56291059
74963620
18672561
93636181
112308742
205944923
318253665
524198588
842452253
1366650841
-2085864202
-719213361
1489889733
770676372
-2034401191
-1263724819
996841286
-266883533
729957753
463074220
1193031973
1656106193
-1445829130
210277063
-1235552067
-1025275004
2034140225
1008865221
-1251961850
-243096629
-1495058479
-1738155108
1061753709
-676401399
385352310
-291049089
94303221
-196745868
-102442647
-299188515
-401631162
-700819677
-1102450839
-1803270516
1389245941
-414024575
975221366
561196791
1536418157
2097614948
-660934191
--------------------------------
Process exited after 2.345 seconds with return value 3221225477
Press any key to continue . . .
我不明白为什么它会提供该输出。
答案 0 :(得分:2)
int serie[]={1,1}
声明两个元素的数组。由于数组具有两个元素并且索引从零开始,因此具有有效索引-0和1,即。 serie[0]
是第一个元素,serie[1]
是第二个元素。
int size=2;
while(..) {
serie[size]= ...
size+=1;
}
当size
开始2
时,表达式serie[2] =
无效。数组中没有第三个元素,它会写入未知的内存区域。执行这样的操作是undefined behavior。那里可能有一些其他变量,一些系统变量或另一个程序的内存,或者它会产生鼻恶魔。它是未定义的。
如果要将输出存储在数组中,则需要确保该数组具有足够的元素来容纳输入。
还有一个提示:
int serie[4000000];
可能不起作用,因为它将尝试分配40000000 * sizeof(int)
,假设sizeof(int) = 4
是15.2兆字节的内存。某些系统不允许在堆栈上分配那么多的内存,因此您应该转到动态分配。
答案 1 :(得分:0)
您正在整数溢出,因为int
的大小在一定程度上不足以容纳数字,因此该数字环绕大小并给出了错误的值。
您的程序应类似于:
#include <stdio.h>
int main(void){
long long unsigned series[100] = {1,1};
int size = 2;
while(size < 100){
series[size] = series[size-1] + series[size-2];
printf("%llu\n", series[size-1]);
size += 1;
}
return 0;
}
尽管long long unsigned
的大小在一定程度上也受到限制,斐波纳契中的数字非常大。因此,这将导致打印出更正确的数字,但也会在一定程度上溢出。当数字超过ULLONG_MAX
中声明的常量limits.h
时,它将溢出。
答案 2 :(得分:0)
此代码的问题:
#include <stdio.h>
int main(void){
int serie[]={1,1},sum=0,size=2;
while(size<=4000000){
serie[size]=serie[size-1]+serie[size-2];
printf("%d\n",serie[size-1]);
size+=1;
}
return 0;
}
...是它试图将一个很长的数字系列(400万个)存储到一个很短的数组(2个元素)中。数组的大小是固定的。更改变量size
对数组serie
的大小没有影响。
表达式serie[size]=...
每次执行时都会在数组的边界之外存储数字 ,因为唯一合法的数组索引值为0和1。这会导致未定义的行为< / em>,老实说,您很幸运,只看到了奇怪的输出。
有两种可能的解决方案。更改代码最少的一种方法是简单地扩展数组。请注意,我将其设为静态变量而不是自动变量,因为您的实现可能在其堆栈中不支持该大小的变量。
#include <stdio.h>
int serie[4000000]={1,1};
int main(void){
int size=2;
while(size<4000000){ // note strict less-than: 4000000 is not a valid index
serie[size]=serie[size-1]+serie[size-2];
printf("%d\n",serie[size-1]);
size+=1;
}
return 0;
}
更通用的解决方案是将系列中的当前术语和前两个术语存储为三个单独的整数。它的计算量稍高一些,但没有巨大的内存需求。
#include <limits.h>
#include <stdio.h>
int main(void)
{
int term0=0, term1=1, term2;
while(1)
{
if (term0 > INT_MAX - term1) break;// overflow, stop
term2 = term0 + term1;
printf("%d\n",term2);
term0 = term1;
term1 = term2;
}
return 0;
}
这还有一个好处,就是它不会打印出任何超出“ int”表示范围的数字,而这些数字“四处包裹”。当然,您可以轻松地选择另一种数据类型,以获得更长的有效输出序列。
答案 3 :(得分:0)
您有两个问题:
serie
中分配更多的空间
使用查看修改后的代码:
#include <stdio.h>
// Set maximum number of fib numbers
#define MAX_SIZE 90
int main(void) {
// Use 64 bit unsigned integer (can't be negative)
long long unsigned int serie[MAX_SIZE];
serie[0] = 1;
serie[1] = 1;
int sum = 0;
int size = 0;
printf("Fib(0): %llu\n", serie[0]);
printf("Fib(1): %llu\n", serie[1]);
for (size = 2; size < MAX_SIZE; size++) {
serie[size] = serie[size-1] + serie[size-2];
printf("Fib(%i): %llu\n", size, serie[size]);
}
return 0;
}
由于您只打印数字,因此实际上不必存储所有数字 (只有前两个数字),但是如果只有90个,这真的没关系。