通过引用将指针传递给2-D数组

时间:2012-10-14 00:30:19

标签: c++ multidimensional-array

我只是想知道 - 这是通过函数引用将指针传递给二维数组的正确方法吗?

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

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

感谢。

3 个答案:

答案 0 :(得分: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))
     ....
}

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

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

有关详细信息,您可能需要阅读this answer to this question

答案 1 :(得分:2)

C数组非常混乱,C ++继承了与C兼容的混淆。为了理解数组的工作方式,基础是:

1)数组变量在表达式中表现为指向其第一个元素的指针,除了它是常量(即你不能做“array = p;”)和sizeof(数组)将给你数组的大小(size一个元素乘以元素的数量)而sizeof(指针)将给出指针的大小。

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“test”元素数组的数组。

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

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

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

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

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

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

答案 2 :(得分: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)

请注意,唯一的区别是将*(指针)更改为&(引用)。使用它将是:

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

正如您所看到的,通过更改函数参数的类型,第一个维度现在是 free ,编译器很乐意接受任何大小,因此它是比原来更糟糕的选择。

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