使用指向2D阵列的一维指针数组?

时间:2012-07-27 20:37:26

标签: c++ arrays pointers

所以我正在开发一个Tic-Tac-Toe游戏,对于我的输入功能,我得到了玩家在二维数组中作为整数存储的移动,输入是使用对一维数组的引用得到的指向2D数组中位置的指针。

然而我的问题是,当我似乎通过使用指针将多维数组的平方值设置为某个东西时,没有任何反应。

这是输入功能:

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. 但是这似乎不会发生。当我之后运行单元格时,板[0] [0]似乎没有设置为1,并且它不会反映在我的数组中。我在这里弄乱指针吗?

5 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:3)

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

BTW,paranthesis和loop是你的朋友:

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);
}

答案 2 :(得分:2)

将方法签名更改为

void Game::input(Board& b) 

通过这种方式,您实际上会看到您对其所做的更改。 此时您正在按值调用方法。

答案 3 :(得分:2)

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

答案 4 :(得分: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]);

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