我正在制作TICTAC Toe游戏。我正在使用2D数组,我在函数调用中调用和传递数组时遇到问题 这个错误是什么意思?
char mark=move(matrix,turn,yourTurn);
我的功能是:
int move(char matrix[3][3],int turn,int &move)
{
char mark;
if(turn==1)
{
mark='X';
}
else
mark='O';
switch (move)
{
case 1:
matrix[0][0]=mark;
return matrix[0][0];
case 2:
matrix[0][1]=mark;
return matrix[0][1];
case 3:
matrix[0][2]=mark;
return matrix[0][2];
case 4:
matrix[1][0]=mark;
return matrix[1][0];
case 5:
matrix[1][1]=mark;
return matrix[1][1];
case 6:
matrix[1][2]=mark;
return matrix[1][2];
case 7:
matrix[2][0]=mark;
return matrix[2][0];
case 8:
matrix[2][1]=mark;
return matrix[2][1];
case 9:
matrix[2][2]=mark;
return matrix[2][2];
default:
cout<<"You can only mark 1 to 9 on the board";
break;
}
}
isFull()函数此函数告诉我该位置是否已填充。它尚未完整,因为我被卡住了。
bool isFull(char matrix[3][3])
{
for (int row = 0; row < 3; row++)
{
for (int col = 0; col < 3; col++)
{
if (matrix[row][col]=='X'||matrix[row][col]=='O')
{
return true;
}
}
}
return false;
}
答案 0 :(得分:0)
让我通过简化来帮助您完成代码:
#include <array>
using namespace std;
// ...
int move(array<array <char, 3>, 3 > &matrix, const int turn, const int moveVal)
{
char mark;
if(turn==1)
{
mark='X';
}
else
{
mark='O';
}
if(moveVal <= 0 || moveVal > 9)
{
cout<<"You can only mark 1 to 9 on the board";
}
else
{
const int x = (moveVal-1) % 3;
const int y = (moveVal-1) / 3;
matrix[x][y]=mark;
}
return mark;
}
因为这是C ++代码,为什么不传递对数组数组的引用?为什么?那么经典的C阵列也是指针,在我看来对初学者来说有点混乱。除非你想更多地进入C风格,否则我不会打扰他们。二维数组最好被视为一维数组中的步幅,因为你的内存总是一维的,你必须找到一种方法来处理它。
如果你定义一个像char matrix[3][3]
这样的静态二维数组,编译器会自动知道它将成为一个包含不同访问模式的九个元素的数组。如果你让这个数组更具动态性,大小可以改变等等,你的内存管理很可能会将它分成不同的片段。
这就是为什么带有STL的C ++具有std::vector
和std::array
作为模板的原因,它们本身可以组合在一起。尝试使用这些,除非您想要了解有关C中的内存管理,数组和指针的更多信息。
答案 1 :(得分:-1)
错误很有趣,而且对于您提供的代码没有警告。可能摩尔比迪诺的预感是正确的,在某个地方有一个你没有告诉我们的声明。为什么不提出一个完整的,最小的例子呢?事实上,这种努力可能已经解决了你的问题,而不是在这里问.--
使用您提供的函数签名int move(char matrix[3][3],int turn,int &move)
,编译器会忽略参数声明的第一个维度。该函数只需要一个指向三个int数组的指针。在C(以及C ++的C-ish部分)中,没有直接的方法将数组传递给函数,因为这是数组&#34;衰变的地方之一。指向其第一个元素的指针。 (除了第一个维度之外的所有其他维度都相关的原因是索引结果指针需要有关其指向的元素大小的信息,这是从剩余维度计算得出的。)
以下声明是等效的:
void isFull(int arr[3][3]); // first dimension is ingnored
void isFull(int arr[100][3]); // first dimension is ingnored anyway
void isFull(int arr[][3]); // is equivalent to the next one
void isFull(int (*arr)[3]); // this is what actually is declared and passed
在C ++中,有可能将引用传递给数组,这些数组会保留&#34;所有数组维度(顺便说一句,指向数组的指针也会这样做,即使在C中;它只是不那么常见)。缺点当然是它的灵活性较低,因为阵列的大小是硬编码的。在你的Tic Tac Toe的情况下,虽然不是问题。
这是一个说明问题的小程序。请注意,在具有不同大小的数组的注释掉调用中,编译器仅会抱怨第二个参数,即引用。它不关心第一个参数指向的内存位置后面有多少个元素。
#include <iostream>
using namespace std;
void f(int arr[100][3], int (&arr_ref)[4][3])
{
cout << "size of arr parameter: " << sizeof(arr) << endl;
cout << "size of pointer: " << sizeof(int *) << endl << endl;
cout << "size of first arr element: " << sizeof(*arr)
<< " (which is " << sizeof(*arr)/sizeof(**arr)
<< " times the size of *its* elements)" << endl << endl;
cout << "size of object arr ref refers to: " << sizeof(arr_ref)
<< " (which is " << sizeof(arr_ref)/sizeof(**arr_ref)
<< " times the size of an int, " << sizeof(int) << ")." << endl;
}
int main()
{
int arr[4][3];
int wrong_arr[5][3];
// f(wrong_arr, wrong_arr);
// 2d-array-param-decl.cpp: In function ‘int main()’:
// 2d-array-param-decl.cpp:23:24: error: invalid
// initialization of reference of type ‘int (&)[4][3]’
// from expression of type ‘int [5][3]’
// f(wrong_arr, wrong_arr);
// ^
// 2d-array-param-decl.cpp:5:6: note: in passing argument 2
// of ‘void f(int (*)[3], int (&)[4][3])’
// void f(int arr[100][3], int (&arr_ref)[4][3])
// ^
f(arr, arr);
return 0;
}
示例会话:
$ g++ -Wall -o 2d-array-param-decl 2d-array-param-decl.cpp && ./2d-array-param-decl
2d-array-param-decl.cpp: In function ‘int main()’:
2d-array-param-decl.cpp:27:6: warning: unused variable ‘wrong_arr’ [-Wunused-variable]
int wrong_arr[5][3];
^
size of arr parameter: 8
size of pointer: 8
size of first arr element: 12 (which is 3 times the size of *its* elements)
size of object arr ref refers to: 48 (which is 12 times the size of an int, 4).