0

所以我在做一个井字游戏,对于我的输入函数,我得到了玩家将移动存储为二维数组中的整数,输入是使用对指向位置的指针的一维数组的引用获得的在二维数组中。

但是我的问题是,当我似乎通过使用指针将多维数组的平方的值设置为某个值时,什么也没有发生。

这是输入函数:

void Game::input(Board b){
int *spots[9]; // Possible spots for the input
bool validInput = false;
spots[0] = &b.board[2][0];
spots[1] = &b.board[2][1];
spots[2] = &b.board[2][2];
spots[3] = &b.board[1][0];
spots[4] = &b.board[1][1];
spots[5] = &b.board[1][2];
spots[6] = &b.board[0][0];
spots[7] = &b.board[0][1];
spots[8] = &b.board[0][2];
redo:
    cout << ">> " << endl;
    int input; // Input
    cin >> input; // Get the input
    validInput = cin;
    if(!validInput){
        cout << "Numbers only please!" << endl;
        cin.clear();
        while(cin.get() != '\n');
        goto redo;
    }
    if(input > 9 || input <= 0){
        cout << "Invalid move!" << endl;
        goto redo;
    }
    input--; // Subtract 1 for array location
    if(*spots[input] != 0){
        cout << "Square is already being used!" << endl;
        goto redo;
    }
    *spots[input] = 1;
}

现在,假设我输入了数字 7。它应该将 b.board[0][0] 设置为 1。但是这似乎没有发生。当我之后运行一个单元案例时, board[0][0] 似乎没有设置为 1,并且它没有反映在我的数组中。我在这里搞砸了关于指针的事情吗?

4

5 回答 5

6

函数的参数是按值传递的,因此您对其所做的任何更改都不会被识别,因为按值传递会创建参数的副本。考虑改为通过指针或引用传递。

于 2012-07-27T20:41:33.673 回答
3

您通过值而不是指针/引用传递Board实例。input()您对该Board实例所做的任何更改都不会反映在Board传递给的原始实例中input()

顺便说一句,括号和循环是你的朋友:

void Game::input(Board &b)
{ 
    int* spots[9]; // Possible spots for the input 
    bool validInput; 
    int input;
    spots[0] = &(b.board[2][0]);
    spots[1] = &(b.board[2][1]); 
    spots[2] = &(b.board[2][2]); 
    spots[3] = &(b.board[1][0]); 
    spots[4] = &(b.board[1][1]); 
    spots[5] = &(b.board[1][2]); 
    spots[6] = &(b.board[0][0]); 
    spots[7] = &(b.board[0][1]); 
    spots[8] = &(b.board[0][2]); 
    do
    {
        std::cout << ">> " << std::endl; 
        std::cin >> input; // Get the input 
        validInput = std::cin; 
        if (!validInput)
        { 
            std::cout << "Numbers only please!" << std::endl; 
            std::cin.clear(); 
            while (std::cin.get() != '\n'); 
            continue; 
        } 
        if ((input > 9) || (input <= 0))
        { 
            std::cout << "Invalid move!" << std::endl; 
            continue; 
        } 
        --input; // Subtract 1 for array location 
        if (*spots[input] != 0)
        { 
            std::cout << "Square is already being used!" << std::endl; 
            continue; 
        } 
        *spots[input] = 1; 
        break;
    }
    while (true);
}
于 2012-07-27T20:46:13.127 回答
2

将您的方法签名更改为

void Game::input(Board& b) 

这样,您实际上会看到您对其所做的更改反映出来。目前,您正在按值调用该方法。

于 2012-07-27T20:43:23.713 回答
2

您可以尝试的另一件事是选择移动的一点数学。假设用户输入 7. 7/3 = 2,即行。7 % 3 = 1,列。所以 7 指的是board[2][1],这是正确的点。

于 2012-07-27T20:43:48.430 回答
0

您的输入函数声明为:

void Game::input(Board b)

当您从另一个函数调用它时,例如

Board tictactoe;
Game g;

g.input(tictactoe);

b获得. _ _ tictactoe您在input()函数中所做的任何更改b都不会反映在tictactoe.

您至少有两种解决方案:

1) 参考传板:

void Game::input(Board& b)

2)或将指针传递给板:

void Game::input(Board* b)

还有其他解决方案需要重新设计您的代码。这两种可能是解决当前问题的最简单、最直接的方法。

此外,将索引从一维数组映射到二维数组的方式对我来说似乎有点奇怪。我认为如果你有

spots[0] = &(b.board[0][0]); 
spots[1] = &(b.board[0][1]);  
spots[2] = &(b.board[0][2]);  
spots[3] = &(b.board[1][0]);  
spots[4] = &(b.board[1][1]);  
spots[5] = &(b.board[1][2]);  
spots[6] = &(b.board[2][0]);  
spots[7] = &(b.board[2][1]);  
spots[8] = &(b.board[2][2]);

事实上,正如其他人所指出的,这是不必要的,因为您可以从输入中计算行和列索引。或者,您可以要求用户输入两个数字,而不仅仅是一个。

于 2012-07-27T20:45:52.510 回答