Невозможно вызвать функцию без застревания в бесконечном цикле

Когда следующая функция вызывается и запускается, если выполняется начальное условие «если», программа запускается, как предполагалось; повторно. Если начальное условие «если» не выполняется, программа переходит к выполнению оператора else, но застревает в бесконечном цикле.

Почему?

#include <stdio.h>
#include <string.h>

int num_func();

int main()
{
    num_func();

   return 0;
}

int num_func()
{
    int num;
    char yn[1];

    printf("Please enter an integer value: ");

    if (scanf("%d", &num) == 1)

        {
            printf("The value you entered is: %d. Is this correct? ", num);
            scanf("%s", &yn);

            if (strcmp(yn, "y") == 0) {
                printf("Great! \n");
            }

            else if (strcmp(yn, "n") == 0) {
                printf(":( \n");
            }

            else {
                printf("Illegal Entry. \n");
            }
        }

    else {
        printf("You were told to put in a number!");
    }

    num_func();
}

Мне также интересно узнать, как сделать глобальные переменные num и yn[1], чтобы num_func() мог получить к ним доступ без необходимости выделять память при каждом запуске. Если бы вы могли объяснить это, я был бы признателен.

потому что вы рекурсивно вызываете функцию в конце самой себя, поэтому она будет повторяться «навсегда» (или до тех пор, пока она не переполнит стек, если оптимизация хвостовой рекурсии не включена во время компиляции).

jodag 28.05.2019 05:19

Но num_func помещается за пределы операторов if else, когда любое из этих условий выполняется, не должен ли компилятор запускать num_func с самого начала вместо того, чтобы циклически выполнять оператор else?

user10003651 28.05.2019 05:21

В функции нет инструкции return, поэтому она никогда не завершается раньше. num_func() будет вызываться после выполнения операторов if или else независимо от того, какое условие выполнено.

jodag 28.05.2019 05:23

я не понимаю

user10003651 28.05.2019 05:25

Программы запускаются последовательно. Как вы думаете, почему последний оператор в num_func (который сам по себе является еще одним вызовом num_func) не будет выполнен?

jodag 28.05.2019 05:25

Я понимаю, что йодаг. Я понимаю, что функция будет работать бесконечно. это то, что я хочу. Я пытаюсь понять, почему, если «num_func() будет вызываться после выполнения операторов if или else независимо от того, какое условие выполнено», он не начинается с TOP, где пользователю предлагается ввести целочисленное значение

user10003651 28.05.2019 05:29

О, моя ошибка. Я неправильно понял вопрос, я думал, вы спрашиваете, почему в случае, когда else называется бесконечным циклом, он не заканчивается.

jodag 28.05.2019 05:31

Вы не виноваты, я двусмысленно сформулировал, ошибка моя

user10003651 28.05.2019 05:35

Используйте цикл while вокруг num_func, а не рекурсию. Это плохая форма.

hookenz 28.05.2019 05:43

Возможный дубликат C: scanf для char не работает должным образом

hookenz 28.05.2019 05:54
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
10
78
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

После ответа здесь. При неверном вводе stdin не будет очищен, поэтому вам нужно очистить его самостоятельно. В противном случае при следующем вызове scanf он увидит, что еще есть данные для чтения, и попытается снова прочитать недопустимые данные.

#include <stdio.h>
#include <string.h>

int num_func();

int main()
{
    num_func();

   return 0;
}

int num_func()
{
    int num, c;
    char yn[1];

    printf("Please enter an integer value: ");

    if (scanf("%d", &num) == 1)

        {
            printf("The value you entered is: %d. Is this correct? ", num);
            scanf("%s", &yn);

            if (strcmp(yn, "y") == 0) {
                printf("Great! \n");
            }

            else if (strcmp(yn, "n") == 0) {
                printf(":( \n");
            }

            else {
                printf("Illegal Entry. \n");
                while ((c = getchar()) != EOF && c != '\n')
                    continue;
            }
        }

    else {
        printf("You were told to put in a number!\n");
        while ((c = getchar()) != EOF && c != '\n')
            continue;
    }

    num_func();
}

Что касается второго вопроса, то делать переменную глобальной для экономии места здесь совершенно не нужно, поскольку функция уже имеет пренебрежимо малый кадр стека.

Не могли бы вы объяснить, что здесь происходит в этих строках? while ((c = getchar()) != EOF && c != '\n') continue;

user10003651 28.05.2019 05:54
getchar извлекает один символ из входного потока stdin, где считываются символы. Этот цикл продолжает повторяться до тех пор, пока не будет найден либо EOF (значение, указывающее, что конец буфера достигнут), либо символ новой строки \n, указывающий на конец записи. В этом случае левое выражение оценивается первым, гарантируя, что c установлено на следующее значение в буфере.
jodag 28.05.2019 06:02

Хорошо, позвольте мне понять это прямо. Когда в scanf вводится нецелочисленное значение, а scanf ожидает целочисленное значение, тогда scanf сохраняет нецелочисленное значение как 0 до тех пор, пока не будет запущена вся программа, после чего оно изменит значение на EOF. Понятно, почему мы включаем это в условие цикла while, но я не понимаю, где \n «найден» и почему это включено в условие.

user10003651 28.05.2019 06:26

Проблема здесь заключалась в том, что после ввода оператора else и запуска scanf, который находится в условии if, невозможно принять ввод, потому что буфер ввода-вывода не очищен, и, согласно вашему желанию, я сделал num и yn[] глобальными.

#include <stdio.h>
#include <string.h>

int num_func();
int num, c;
char yn[1];
int main()
{
    num_func();

    return 0;
}

int num_func()
{

    printf("Please enter an integer value: ");
    fflush(stdin);
    if (scanf("%d", &num) == 1)

        {
            printf("The value you entered is: %d. Is this correct? ", num);
            scanf("%s", &yn);

            if (strcmp(yn, "y") == 0) {
                printf("Great! \n");
            }

            else if (strcmp(yn, "n") == 0) {
                printf(":( \n");
            }

            else {
                printf("Illegal Entry. \n");

            }
        }

    else {
        printf("You were told to put in a number!\n");

    }

    num_func();
}

Другие вопросы по теме