Я пытаюсь написать программу, которая должна находить простые числа от 5 до максимального числа, самое большое число, которое она может найти, это 64927, и это простое число (я думаю, что оно занимает 6489-е место среди простых чисел). когда я устанавливаю max_list_size на 6488, программа работает нормально и завершается с 0, но для большего числа она аварийно завершает работу с кодом = 3221225725 (ошибка в выполняемом программном обеспечении, вызывающая переполнение стека, что приводит к аварийному завершению программного обеспечения), можете ли вы помогите мне ребята?
#include<stdlib.h>
#include<math.h>
long to_which_index ();
void is_prime();
void pluse_two();
void write_to_arrays();
long* prime_numbers;
long current_number = 5;
long next_prime_number = 0;
void terminate ();
long max_list_size = 6488;
int main()
{
prime_numbers = (long*)calloc(max_list_size,sizeof(long));
prime_numbers[0] = 3;
is_prime(current_number);
}
//is prime
void is_prime()
{
int to_which = to_which_index();
for (long i = 0; i <= to_which; i++)
{
//(current_number % prime_numbers[i] == 0) ? pluse_two() : continue ;
if ((current_number % prime_numbers[i]) == 0)
{
pluse_two();
}
}
write_to_arrays();
}
// pluse_2
void pluse_two()
{
current_number = current_number +2;
is_prime();
}
//write
void write_to_arrays()
{
FILE* fptr;
fptr = fopen("G:/Code/files_to_accses/prime_numbers.txt","a");
next_prime_number ++;
prime_numbers[next_prime_number] = current_number;
fprintf(fptr,"%i\n",current_number);
fclose(fptr);
terminate();
}
//terminate programm
void terminate ()
{
if (next_prime_number ==(max_list_size - 1))
{
free(prime_numbers);
exit(0);
}
pluse_two();
}
//from index 0 to which index whe should check?
long to_which_index ()
{
for (long i = 0; i < (next_prime_number+1); i++)
{
//( prime_numbers[i] < ceil(sqrt(double(current_number))) ) ? continue: return i;
if ( prime_numbers[i] < ceil(sqrt(current_number)) )
{
continue;
}
else{
return i;
}
}
}```
У вас закончился стек, потому что вы слишком глубоко рекурсируете, поиск простых чисел не очень хорошее использование рекурсии
Exception thrown at 0x00007FFAAC6E341C (ntdll.dll) in ConsoleApplication3.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x0000003902E03FF8).
Для меня он умер, когда current_number == 2801
Также эта функция
long to_which_index()
{
for (long i = 0; i < (next_prime_number + 1); i++)
{
//( prime_numbers[i] < ceil(sqrt(double(current_number))) ) ? continue: return i;
if (prime_numbers[i] < ceil(sqrt(current_number)))
{
continue;
}
else {
return i;
}
}
}
не возвращает значение все время (это не так)
Вот ваша рекурсия
//is prime
void is_prime() <<<<===================================|
{ |
int to_which = to_which_index(); |
for (long i = 0; i <= to_which; i++) |
{ |
//(current_number % prime_numbers[i] == 0) ? pluse_two() : continue ; |
if ((current_number % prime_numbers[i]) == 0) |
{ |
pluse_two();========================| |
} | |
} | |
write_to_arrays(); | |
| |
} | |
| |
// pluse_2 | |
void pluse_two() <<<<<<======================== | |
{ |
current_number = current_number + 2; |
is_prime(); ==========================================
}
вы можете ясно видеть это в трассировке стека, которую я добавил в качестве снимка экрана
Просто измените эту функцию plus_two следующим образом:
void pluse_two()
{
current_number = current_number + 2;
// is_prime();
}
если вы имеете в виду рекурсивную функцию, я не понимаю, где использовать рекурсивную функцию, которую я сделал, основная часть проблемы - это перебор простых чисел, которые программа уже нашла! Я думаю, что цикл for не считается рекурсивной функцией, потому что он не вызывает сам себя! Если вы думаете о других функциях, я не понимаю концепцию углубления, в дополнение к каждому простому числу каждая функция вызывает другую функцию один раз на уровне один и возвращается в цикл.
А в случае с функцией to_what_index, я думаю, она возвращает значение каждый раз, когда звучит, потому что он проходит между списком чисел и находит число, которое больше второго прилива текущего числа, и он его обязательно находит. Если вы не согласны со мной, можете ли вы дать мне номер?
@DanialHamedi Я подозреваю, что ты просто хочешь вернуться туда
@DanialHamedi исправлено, см. последнее редактирование
Большое спасибо, я заметил проблему, спасибо за руководство! Вы знаете, как я могу решить проблему? Я думаю, что если я объединим функцию pluse_two и функцию is_prime, программа сможет найти больше простых чисел, прежде чем она взорвется (= Если я сделаю это с одним из функциональных языков программирования (например, python), у меня все еще будут проблемы?
@DanialHamedi, вы видели, что комментирование этого рекурсивного вызова работает нормально (см. последнее редактирование). Python потерпит неудачу так же