c - 有什么办法可以避免使用 exit(0)?

标签 c recursion

我想练习一下将逻辑分离到函数中,并在原始的“猜我的数字游戏”中使用基本递归,作为一种查看我在 C 编程中所处位置的方法。

代码如下:

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0

char playAgain()
{
    printf("\nDo you wanna play again? ");
    char resp = 0;
    while (TRUE) {
        scanf("%c", &resp);
        if (resp == 'y') break;
        if (resp == 'n') break;
    }
    return resp;
}

void play()
{
    srand((int)time(NULL));
    int num = rand() % 10 + 1;
    int guess = 0;
    int flag = 0;
    int attempts = 0;

    printf("\nGuess the number: \n");
    while (TRUE) {
        scanf("%d", &guess);
        if (num > guess)
        {
            printf("Too low! ");
            attempts++;
        }
        else if (num < guess)
        {
            printf("Too high! ");
            attempts++;
        }
        else if (num == guess)
        {
            attempts++;
            printf("You won! You did it in %d attempts", attempts);
            char yo = playAgain();
            if (yo == 'y') play();
            else if (yo == 'n') exit(0);
            else {
                printf("Error!");
                exit(1);
            }
        }
    }


}

int main()
{
    return play();
}

一切正常,但我只能在用户说“n”时使用 exit(0) 让它退出,我听说这是不好的做法。但是花了几个小时四处闲逛并尝试了我能想到的所有其他方法(例如,使用标志),我就是无法让它工作。它适用于“y”,但只要我输入“n”,它就不会退出,只是再次调用 playAgain() 函数,或者完全卡住(没有任何反应)。

我为无法解决这个问题而感到羞愧,但我没有想法。除了exit(0),还有什么办法让它直接跳出play(),在main()中返回0?问题似乎是我有一个无限游戏循环,所以当答案为“n”时,我需要跳出循环并跳出 play() 函数,这已被证明是有问题的。我记得当我没有函数时能够轻松地做到这一点,但只有 main() 中的所有相关代码,但这的全部意义在于使用函数。例如,我不知道如何使用 play() 的返回类型,以便它知道何时退出。

附言与往常一样,看到人们经常被指责,我向你保证这不是家庭作业,因为我一直并将编程严格地作为一种爱好。除了您之外,没有我要回答的教授 :-) 请相信我,我确实尝试找出解决方案,但似乎没有任何效果。这是一个好与坏设计的问题,所以这对我的自学尤为重要。 exit(0) 似乎是一个 hackish 解决方案,没有任何教育目的。

附言顺便说一下,我正在使用 xCode,程序在其输出窗口中运行。可能不是,但也许这就是用 'n' 退出不起作用的原因?

总结:代码工作正常,除非答案是“n”,在这种情况下它只是询问“你想玩吗?”再次,或者根本不做任何事情。

最佳答案

让您的播放函数返回结果:- int play( void ) {

然后代替 exit(1)exit(0);使用 return 1;return 0;

在播放结束时放return 0;

然后在主

{
return play();
}

不用递归,只做一个循环

int play( void)
{
    srand((int)time(NULL));
    int num;
    int guess;
    int flag;

    while(1)
    {
        num = rand() % 10 + 1;
        guess = 0;
        flag = 0;
        printf("\nGuess the number %d: \n", num);
        while (1) {
            scanf("%d", &guess);
            if (num > guess)
            {
                printf("Too low! ");
            }
            else if (num < guess)
            {
                printf("Too high! ");
            }
            else if (num == guess)
            {
                printf("You won!");
                char yo = playAgain();
                if (yo == 'y') break;
                else if (yo == 'n') return 0;
                else {
                    printf("Error!");
                    return  1;
                }

            }
        }
    }


}

如果你想要更多的游戏引擎类型的方法

enum {  
    GUESS,
    GAMEOVER,
    QUIT,

} GAME_STATES;

typedef struct 
{
    enum GAME_STATES state;
    int num;    
    int game_over;
} guessing_game_t;


void init_game(guessing_game_t* g)
{   
    g->state = GUESS;
    g->game_over = 0;
    g->num = rand() % 10 + 1;
}

void evaluate_guess(guessing_game_t* g, int guess)
{
    if(g->num == guess)
    {
        printf("You won!");
        g->state = GAMEOVER;
    }
    else if (g->num > guess)
    {
        printf("Too low! ");
    }
    else if (g->num < guess)
    {
        printf("Too high! ");
    }
}

int input_guess( void )
{
    int guess;
    scanf("%d", &guess);
    return guess;
}

void play_again( guessing_game_t* g)
{   
    char resp = 0;

    printf("\nDo you wanna play again? ");
    scanf("%c", &resp);
    if (resp == 'y') init_game(g);
    if (resp == 'n') g->state = QUIT;

}

void play( guessing_game_t* g)
{
    while(g->state != QUIT)
    {
        switch(g->state)
        {
        case GUESS:
            evaluate_guess(g, input_guess());
            break;
        case GAMEOVER:
            play_again(g);
            break;
        }
    }
}

int main()
{
    guessing_game_t game;
    init_game(&game);
    play(&game);
}

关于c - 有什么办法可以避免使用 exit(0)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22137805/

相关文章:

algorithm - 对数运行时间和尾递归

algorithm - Big O n^(lg3) 中的 Karasuba 算法通过替换证明

检查我对特定角色的内存 - 做不到

objective-c - 将多维 NSMutableArray 中的数据提取到更简单的数组中

java - 努力保持算法以通过掷骰子整齐地排序玩家

java - 退出 void 递归 Java 函数的更顺畅的方法

c - gdb x 命令的 c 格式输出

c - 打印到标准输出时 printf 产生额外的 %

objective-c - 是否可以通过宏将关键字封装成Obj-C String?

javascript - 如何将 JavaScript 对象扁平化为类似菊花链的形式?