0

我只是想知道——这是在函数中通过引用传递指向二维数组的指针的正确方法吗?

bool test::testTheNumber(test (*arr)[9][9], int testNumber, int row, int column)
{
    if(theRow(arr, testNumber, row) && theColumn(arr, testNumber, column))
     ....
}

我的“theRow”和“theColumn”答案与测试函数非常相似:

bool sodoku::theRow(sodoku (*arr)[9][9], int testNumber, int row)

bool sodoku::theColumn(sodoku (*arr)[9][9], int testNumber, int column)

在我的 main.cpp 中,我有一个指向二维数组的指针,我这样调用我的函数:

test *arr[9][9];
theRow(arr,0,0);
theColumn(arr,0,0);
testTheNumber(arr,0,0,0,0);

数组是通过引用传递还是必须使用 & 而不是 *?我只是有点困惑,因为我不完全确定二维数组将如何工作。

谢谢。

4

3 回答 3

2

bool test::testTheNumber(test (*arr)[9], int testNumber, int row, int column)
{
    if(theRow(arr, testNumber, row) && theColumn(arr, testNumber, column))
     ....
}

或者

bool test::testTheNumber(test arr[][9], int testNumber, int row, int column)
{
    if(theRow(arr, testNumber, row) && theColumn(arr, testNumber, column))
     ....
}

不需要数组中的第一个维度。

实际上,默认情况下,数组是通过引用传递的。你不需要一个&.

有关更多信息,您可能需要阅读此问题的答案

于 2012-10-14T00:38:20.383 回答
2

C 数组非常混乱,C++ 继承了与 C 兼容的混乱。要了解数组的工作原理,基础知识是:

1)数组变量在表达式中表现为指向其第一个元素的指针,除了它是常量(即您不能执行“array = p;”)并且 sizeof(array) 将为您提供数组的大小(一个元素的大小乘以元素的数量),而 sizeof(pointer) 将为您提供指针的大小。

int array[5];
int* p = array;

那么下面的表达式为真:

array[0] == *array
sizeof(array) == sizeof(int)*5
sizeof(p) == sizeof(void*)

2) 当您将函数的参数定义为数组时,它总是作为指向第一个元素的指针传递。并且在函数中表现得如此。实际上,在这种情况下,C 会忽略传递数组的大小。更重要的是,在函数中将参数定义为数组或指向数组元素的指针被编译器认为是相同的。所以:

void func(int array[5]);
void func(int array[]);
void func(int *array);

声明完全相同的函数,在这个函数内部,sizeof(array)==sizeof(void*)

因此,数组似乎总是通过引用传递,看起来像是指向其第一个元素的指针。

现在,多维数组实际上只是一维数组,其元素是数组。C/C++ 中令人困惑的部分是 C/C++ 通常定义类型的令人困惑的方式。所以:

test* array[9][9];

请记住,要读取 C/C++ 类型,您从标识符开始,并且 [] 和 () 具有优先级,因此数组是 9 个元素的数组(第一个 [9]),它是 9 个元素的数组(第二个 [9])它们是指向“test”类型的指针。

现在对于此方法中的 arr 参数:

bool sodoku::theRow(test (*arr)[9][9], int testNumber, int row)

arr 是指向由 9 个“测试”元素组成的 9 个数组的指针(括号改变优先级)。

这与上面前面的“array”变量非常不同,尤其是因为“array”包含指向“test”的指针,而 arr 包含“test”元素......

顺便说一句,以下声明完全相同:

bool sodoku::theRow(test arr[][9][9], int testNumber, int row)

因为“arr”也可以解释为指向9个数组的第一个元素的指针到9个“test”......

在实践中,您可能想要做的是传递 9 个“测试”数组的数组,所以:

boot sudoku::theRow(test arr[][9], int testNumber, int row)
{ ... }

test array[9][9];
sudoku::theRow(array, 0, 0);

该方法也可以定义为:

boot sudoku::theRow(test (*arr)[9], int testNumber, int row)
{ ... }

互联网上有很多关于这种非常混乱的 C/C++ 数组/指针混合的信息,例如: http: //pw1.netcom.com/~tjensen/ptr/pointers.htm

于 2012-10-14T01:42:30.763 回答
0
bool test::testTheNumber(test (*arr)[9][9], int testNumber, int row, int column)

这是在函数中通过引用传递指向二维数组的指针的正确方法吗?

从技术上讲,这不是通过引用传递数组,而是通过值传递指向数组的指针。其他方面的语义非常相似。要通过引用将9x9 整数数组传递给函数,签名将是:

bool test::testTheNumber(test (&arr)[9][9], int testNumber, int row, int column)

请注意,唯一的区别是将*(pointer) 更改为&(reference)。它的用途是:

int main() {
   test array[9][9];
   test t;
   t.testTheNumber(array,1,2,3);
}

(这是否有意义是完全不同的事情......例如,您可能想要提供非成员函数而不是成员函数)

Geoff 的两个建议都是等效的,它们的问题是在更改接口时,数组的大小在签名中并不固定。也就是说,该函数将采用 9x9 的数组,但它也将接受 2x9,3x9...Nx9 的数组。

bool f(int (*arr)[9]);
int main() {
    int array[9][9];
    f(array);          // ok, but so is:
    int array2[3][9];
    f(array2);
}

正如你所看到的,通过改变函数参数的类型,第一个维度现在是自由的,编译器会很乐意接受那里的任何大小,所以它是一个比原始维度更糟糕的选择。

最后,我的建议是创建一个表示 9x9 矩阵的类型并传递对该类型的引用。

于 2012-10-14T01:22:51.263 回答