【问题标题】:Unable to Call function without being stuck in endless loop无法调用函数而不陷入无限循环
【发布时间】:2019-10-13 12:44:14
【问题描述】:

当调用并运行以下函数时,如果满足初始的“if”条件,则程序按预期运行;反复。如果最初的“if”条件不满足,程序会继续运行 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 语句循环吗?
  • 函数中没有返回语句,所以它永远不会提前退出。 num_func() 将在 if 或 else 语句执行后被调用,无论满足哪个条件。
  • 我不明白
  • 程序按顺序运行。为什么你认为 num_func 中的最后一条语句(它本身是对 num_func 的另一个调用)不会被执行?

标签: c


【解决方案1】:

这里的问题是,在输入 else 语句并运行处于 if 条件的 scanf 后,由于 i/o 缓冲区不清晰,并且根据您的希望,我已将 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();
}

【讨论】:

    【解决方案2】:

    按照答案here。无效输入 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') 继续;
    • getchar 从读取字符的输入流stdin 中弹出一个字符。此循环不断重复,直到找到EOF(表示已到达缓冲区末尾的值)或找到换行符\n,表示条目结束。在这种情况下,首先计算左侧表达式,确保 c 已设置为缓冲区中的下一个值。
    • 好的,让我直说吧。当一个非整数值被输入到 scanf 并且 scanf 期待一个整数值时,scanf 将非整数值存储为 0,直到整个程序运行,之后它将值更改为 EOF。为什么我们在 while 循环的条件中包含它是有道理的,但我不知道 \n 是“找到”的位置以及为什么包含在条件中。
    猜你喜欢
    • 1970-01-01
    • 2017-12-05
    • 2021-12-17
    • 2021-09-24
    • 2020-05-13
    • 1970-01-01
    相关资源
    最近更新 更多