我可以在这种情况下使用goto吗?

时间:2012-03-12 11:54:56

标签: c++ goto

我想知道,如果在这种情况下使用goto ok?你能提出更好的解决方案吗我看到唯一一个在cicle上获得第二个但是那时有必要两次调用“makeMove”。

void BoardView::startGame()
{
    int currStep=0;
    int x,y;
    while (board_->isWin()==none)
    {
        currStep++;
        show();
    wrong:
        std::cout << " Player " << (currStep%2==0 ? 1 : 2) << ": ";
        std::cin >> x;
        y=x%10;
        x/=10;
        if (!board_->makeMove(x,y,(currStep%2==0 ? cross : zero)))
        {
            std::cout << "Wrong move! Try again.\n";
            goto wrong;
        }
    }
}

7 个答案:

答案 0 :(得分:4)

请勿使用goto。在成功移动后,使用while (true)循环和break

while (true) {
    std::cout << " Player " << (currStep%2==0 ? 1 : 2) << ": ";
    std::cin >> x;
    y=x%10;
    x/=10;
    if (board_->makeMove(x,y,(currStep%2==0 ? cross : zero)))
        break;
    std::cout << "Wrong move! Try again.\n";
}

答案 1 :(得分:1)

也许:

void BoardView::startGame()
{
    int currStep=1;
    int x,y;
    show();
    while (board_->isWin()==none)
    {
        std::cout << " Player " << (currStep%2==0 ? 1 : 2) << ": ";
        std::cin >> x;
        y=x%10;
        x/=10;
        if (!board_->makeMove(x,y,(currStep%2==0 ? cross : zero)))
        {
            std::cout << "Wrong move! Try again.\n";
            continue;
        }
        ++currStep;
        show();
    }
}

它不完全相同,但它不使用goto。

答案 2 :(得分:1)

是的,你被允许进行这样的跳跃,尽管通常最好避免goto。你可以这样重写它,例如:

void BoardView::startGame()
{
    int currStep=1;
    int x,y;
    show();
    while (board_->isWin()==none)
    {
        std::cout << " Player " << (currStep%2==0 ? 1 : 2) << ": ";
        std::cin >> x;
        y=x%10;
        x/=10;
        if (board_->makeMove(x,y,(currStep%2==0 ? cross : zero)))
        {
            currStep++;
            show();
        }
        else
        {
            std::cout << "Wrong move! Try again.\n";
        }
    }
}

答案 3 :(得分:1)

一般建议是避免使用GOTO语句,但是,请参阅修改后的代码和

    void BoardView::startGame()
{
    int currStep=0;
    int x,y;
    while (board_->isWin()==none) {

        currStep++;
        show();
        int retry = 0; /* So that 'retry' is visible to do while loop */ 
        do {
              retry = 0;
              std::cout << " Player " << (currStep%2==0 ? 1 : 2) << ": ";
              std::cin >> x;
              y=x%10;
              x/=10;
             if (!board_->makeMove(x,y,(currStep%2==0 ? cross : zero))) {

                std::cout << "Wrong move! Try again.\n";
                retry = 1
             } 

       } while (retry);
    }
}

答案 4 :(得分:0)

你应该尽量避免转到。只有在大型嵌套程序中使用时才能使用。否则使用goto会使程序不可靠,不可读并且难以调试。 goto的另一个大问题是,当我们使用它们时,我们永远无法确定我们如何在代码中达到某一点。它们模糊了控制流。所以避免它们。

我建议使用两个while循环......它会更好......

答案 5 :(得分:0)

出了什么问题:

std::pair<int, int> BoardView::getNextMove()
{
    std::cout << " Player " << (currStep & 2 == 0 ? 1 : 2) << ": ";
    int tmp;
    std::cin >> temp;
    return std::pair<int, int>( tmp / 10, tmp % 10 );
}

void BoardView::startGame() 
{
    int currentStep = 0;
    while ( myBoard->isWin() == none ) {
        std::pair<int, int> move = getNextMove();
        while ( ! myBoard->makeMove( move, (currentStep % 2 == 0 ?  cross : zero) ) {
            std::cout << "Wrong move! Try again" << std::endl;
            move = getNextMove();
        }
    }
}

(虽然我更喜欢Move类型的显式类,而不是 只是std::pair。成员rowcolumn更加明确 比firstsecond。)

通常情况下,如果您被goto(甚至是continue或者break诱惑 {{1}}),这是在单一功能中投入过多的症状。

答案 6 :(得分:0)

两个循环,没有常量条件表达式,只有一次调用makeMove:

void BoardView::startGameLoop()
{
    int currStep = 0;
    int x,y;
    while (none == board_->isWin())
    {
        ++currStep;
        show();

        for (;;)
        {
            std::cout << " Player " << ((currStep & 1) + 1) << ": ";
            std::cin >> x;
            y = x % 10;
            x /= 10;
            if (!board_->makeMove(x, y, (currStep & 1) ? zero : cross))
            {
                std::cout << "Wrong move! Try again.\n";
                continue;
            }
            break;
        }
    }
}