При вводе более 4-значного числа крашится :
#include <stdio.h>
#include <conio.h>
#include <locale.h>
#include <ctype.h>
unsigned int odd(unsigned int x);
unsigned int even(unsigned int x);
int main(void)
{
setlocale(LC_ALL, "Rus");
unsigned int n;
unsigned char c;
do {
printf("\n Введите положительное натуральное число: ");
if (scanf_s("%u%c", &n, &c, 1) != 2 || c != '\n' || n <= 0) {
printf("\n Неправильный ввод. Попробуйте ещё раз.\n");
while (getchar() != '\n') {} // очистить буфер ввода
}
else {
break;
}
} while (1);
unsigned int k = even(n);
unsigned char* answer;
if (k == 1)
{
answer = "чётное";
}
else
{
answer = "нечётное";
}
printf("\n Число %u — %s", n, answer);
printf_s("\n\n Нажмите любую клавишу для выхода из приложения");
_getch();
return 0;
}
unsigned int odd(unsigned int x) {
if (x == 0) {
return 0;
}
else {
return even(x - 1);
}
}
unsigned int even(unsigned int x) {
if (x == 0) {
return 1;
}
else {
return odd(x - 1);
}
}
C/C++
Переполнение стэка на языке Си
"задача сделать с помощью косвенной рекурсии" - тогда запрети ввод более 3х знаков. Можешь, конечно, размер стека увеличить, но тогда будет падать при 5, 6 и т.д.
Либо измени сами функции:
Либо измени сами функции:
bool isOdd( unsigned int x )
{
if( x == 0 ) return true;
if( x == 1 ) return false;
return !isEven( x % 2 );
}
bool isEven( unsigned int x )
{
if( x == 0 ) return false;
if( x == 1 ) return true;
return !isOdd( x % 2 );
}
Мадамин Ташматов
Мне ответили: "а я хочу большое число ввести"
рекурсивные функции очень сильно расходуют место на стеке. Перепишите odd, even без рекурсии.
Если проблема в стеке то путей решения возникшей проблемы тьма
Ну и это все исключая очевидную проверку четности в лоб. n&1==1 или n%2==0
И еще, есть впечатление что проблема этого кода не только в рекурсии, но и в том что указатель на char -- answer указывает на константы в блоке, область видимости которого уже закончилась.
- Можно увеличить шаг рекурсии например для n>10 первый шаг делать return(n-n/10*10);
- Можно рекурсивный алгоритм заменить на итеративный
bool is_even = true;
while(n--)
is_even =!is_even ;
if(is_even){...}
else {...}
- Можно вынести x в область глобальных переменных и не передавать ее значение функции, более того можно и не возвращать значение из функции а по завершении смотреть на значение глобальной переменной x, что может несколько увеличить количество доступных итераций рекурсии.
Ну и это все исключая очевидную проверку четности в лоб. n&1==1 или n%2==0
И еще, есть впечатление что проблема этого кода не только в рекурсии, но и в том что указатель на char -- answer указывает на константы в блоке, область видимости которого уже закончилась.
Мадамин Ташматов
задача сделать с помощью косвенной рекурсии
Николай Чубуков
Ну или чтобы убрать вызов себя непосредственно можно считать odd(x-(x/10)*10-1); при условии что x>=11;
Мадамин Ташматов
Спасибо огромное за помощь
Он мне выдал еще одно задание в нем тоже получается нужно повысить шаг рекурсии:
Он мне выдал еще одно задание в нем тоже получается нужно повысить шаг рекурсии:
Мадамин Ташматов
#include <stdio.h>
#include <locale.h>
#include <conio.h>
#include <ctype.h>
unsigned int leibniz_formula(int n);
unsigned int leibniz_formula_rec(int n, unsigned int sum, unsigned int sign);
int main() {
setlocale(LC_ALL, "Rus");
char c;
int n;
do {
printf_s("\n Введите положительное натуральное число или 'Ctrl + Z' для завершения программы: ");
while (1) {
if (scanf_s("%d%c", &n, &c, 1) != 2 || c != '\n' || n < 0 ) {
printf_s("\n Неправильный ввод. Попробуйте ещё раз: ");
while (getchar() != '\n') {} // очистить буфер ввода
}
else {
break;
}
}
if (c == EOF) {
break;
}
#include <locale.h>
#include <conio.h>
#include <ctype.h>
unsigned int leibniz_formula(int n);
unsigned int leibniz_formula_rec(int n, unsigned int sum, unsigned int sign);
int main() {
setlocale(LC_ALL, "Rus");
char c;
int n;
do {
printf_s("\n Введите положительное натуральное число или 'Ctrl + Z' для завершения программы: ");
while (1) {
if (scanf_s("%d%c", &n, &c, 1) != 2 || c != '\n' || n < 0 ) {
printf_s("\n Неправильный ввод. Попробуйте ещё раз: ");
while (getchar() != '\n') {} // очистить буфер ввода
}
else {
break;
}
}
if (c == EOF) {
break;
}
Мадамин Ташматов
printf_s("Сумма первых %d натуральных чисел по рекурсивной функцие: %d\n", n, leibniz_formula_rec(n, 0, 1));
printf_s("Сумма первых %d натуральных чисел по формуле Лейбница: %d\n", n, leibniz_formula(n));
} while (1);
return 0;
} // 0 1
unsigned int leibniz_formula_rec(int n, unsigned int sum , unsigned int sign ) {
if (n == 0) {
return sum;
}
/*else if (n >= 10) {
sum = (sign * (sign - 10)) / 2;
sum = (sum - (sum / 10)) * 10;
sign++;
sign = (sign - (sign / 10)) * 10;
n = n - (n / 10) * 10;
return leibniz_formula_rec(n, sum, sign);
}*/
sum = (sign * (sign - 1)) / 2;
sign++;
return leibniz_formula_rec(n - 1, sum, sign);
}
printf_s("Сумма первых %d натуральных чисел по формуле Лейбница: %d\n", n, leibniz_formula(n));
} while (1);
return 0;
} // 0 1
unsigned int leibniz_formula_rec(int n, unsigned int sum , unsigned int sign ) {
if (n == 0) {
return sum;
}
/*else if (n >= 10) {
sum = (sign * (sign - 10)) / 2;
sum = (sum - (sum / 10)) * 10;
sign++;
sign = (sign - (sign / 10)) * 10;
n = n - (n / 10) * 10;
return leibniz_formula_rec(n, sum, sign);
}*/
sum = (sign * (sign - 1)) / 2;
sign++;
return leibniz_formula_rec(n - 1, sum, sign);
}
Похожие вопросы
- Решить задачу на языке СИ
- Написать код на языке си
- Написать программу на языке Си
- Помогите с решением задачи на языке СИ
- Си!!! БЕЗ УКАЗАТЕЛЕЙ, ЯЗЫК СИ
- Упорядочить элементы массива по возрастанию на языке Си
- Создать файл ABONENT.dat, содержащий записи следующей структуры: ФИО абонента; его номер телефона. на языке си++
- Помогите с задачей на языке СИ
- Написать код на языке Си
- Написать программу на языке Си, которая решит эту задачу: