Проблема с этим кодом:
#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;
}
... заключается в том, что он пытается сохранить очень длинный ряд чисел (4 миллиона) в очень короткий массив (2 элемента).Массивы имеют фиксированный размер.Изменение переменной size
не влияет на размер массива serie
.
Выражение serie[size]=...
хранит числа вне границ массива каждый раз, когда выполняется , потому чтотолько допустимые значения индекса массива - 0 и 1. Это приводит к неопределенному поведению , и, честно говоря, вам повезло только увидеть странный вывод.
Есть несколько возможных решений.Тот, который меняет ваш код меньше всего, это просто расширить массив.Обратите внимание, что я сделал ее статической, а не автоматической переменной, потому что ваша реализация, вероятно, не будет поддерживать что-то такого размера в своем стеке.
#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».Конечно, вы можете легко выбрать другой тип данных, чтобы получить более длинную последовательность допустимых выходных данных.