Когда следующая функция вызывается и запускается, если выполняется начальное условие «если», программа запускается, как предполагалось; повторно. Если начальное условие «если» не выполняется, программа переходит к выполнению оператора 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() мог получить к ним доступ без необходимости выделять память при каждом запуске. Если бы вы могли объяснить это, я был бы признателен.
Но num_func помещается за пределы операторов if else, когда любое из этих условий выполняется, не должен ли компилятор запускать num_func с самого начала вместо того, чтобы циклически выполнять оператор else?
В функции нет инструкции return, поэтому она никогда не завершается раньше. num_func() будет вызываться после выполнения операторов if или else независимо от того, какое условие выполнено.
я не понимаю
Программы запускаются последовательно. Как вы думаете, почему последний оператор в num_func (который сам по себе является еще одним вызовом num_func) не будет выполнен?
Я понимаю, что йодаг. Я понимаю, что функция будет работать бесконечно. это то, что я хочу. Я пытаюсь понять, почему, если «num_func() будет вызываться после выполнения операторов if или else независимо от того, какое условие выполнено», он не начинается с TOP, где пользователю предлагается ввести целочисленное значение
О, моя ошибка. Я неправильно понял вопрос, я думал, вы спрашиваете, почему в случае, когда else называется бесконечным циклом, он не заканчивается.
Вы не виноваты, я двусмысленно сформулировал, ошибка моя
Используйте цикл while вокруг num_func, а не рекурсию. Это плохая форма.
Возможный дубликат C: scanf для char не работает должным образом
После ответа здесь. При неверном вводе 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;
getchar
извлекает один символ из входного потока stdin
, где считываются символы. Этот цикл продолжает повторяться до тех пор, пока не будет найден либо EOF
(значение, указывающее, что конец буфера достигнут), либо символ новой строки \n
, указывающий на конец записи. В этом случае левое выражение оценивается первым, гарантируя, что c
установлено на следующее значение в буфере.
Хорошо, позвольте мне понять это прямо. Когда в scanf вводится нецелочисленное значение, а scanf ожидает целочисленное значение, тогда scanf сохраняет нецелочисленное значение как 0 до тех пор, пока не будет запущена вся программа, после чего оно изменит значение на EOF. Понятно, почему мы включаем это в условие цикла while, но я не понимаю, где \n «найден» и почему это включено в условие.
Проблема здесь заключалась в том, что после ввода оператора 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();
}
потому что вы рекурсивно вызываете функцию в конце самой себя, поэтому она будет повторяться «навсегда» (или до тех пор, пока она не переполнит стек, если оптимизация хвостовой рекурсии не включена во время компиляции).