将2D数组传递给函数

时间:2010-07-06 12:16:40

标签: c++ pointers multidimensional-array

这不是一个问题,“如何将其传递给函数?”但是,“这可以接受吗?”

void func( int **ptr );

int main( int argc, char* argv[] )
{
    int arr[][3] = {{1, 2,}, {3, 4}, {5, 6}};
    int *pArr = *arr;

    (&pArr[0])[1] = 3;

    func(&pArr);

    cin.get();
    return 0;
}

void func( int **ptr )
{
    cout << "In func()" << endl;
    ptr[0][1] = 5;
}

据我所知,这是有效的。它对我来说并不是很安全,但我更喜欢将2D数组传递给函数。而是一个为我工作的指针。

对于那些必须阅读我的代码的人来说,这会非常混乱吗?我应该使用其他方法吗?使用指向数组的指针是一个坏主意吗?

另外,质疑一点偏离主题。我为什么要写:

int arr[] = { 1, 2, 3, 4, 5 };
int *pArr = *arr;

但为什么我不能写

int arr[][3] = {{1, 2,}, {3, 4}, {5, 6}};
int *pArr = **arr;

甚至使用** pArr?

3 个答案:

答案 0 :(得分:6)

你在这里感到困惑。 int arr[][3] = {{1, 2,}, {3, 4}, {5, 6}};指向长度为3的数组的指针。它是一个单个固体内存块9 int s长,它会衰减为单个int*。编译器为您的单个内存块执行3 * first + second映射。

函数中的下标无效的原因是因为函数无法确定数组的维数。使用单维数组,您不需要此信息 - 您只需将索引添加到给定的基指针。但是,对于二维数组,您需要维度来计算最终索引。

您的函数中的

ptr[0][1] = 5;正在被翻译为*((*(ptr + 0)) + 1) = 5;,这显然不是您想要的arr不是指针数组。

编辑:回应评论:

  

ptr [0] [1]会覆盖数组[0] [1]中的信息

是的,你在这里很幸运 - 这就是原因。将数组传递给函数时,传递了(&pArr[0])[1],它是指向数组第一个元素的指针。当您执行*((*(ptr + 0)) + 1) = 5;时,ptr+0成为无操作,离开*(*ptr + 1) = 5;,根据您的输入数据,它确实具有明确定义的行为(它将arr视为单个 - 维数组)。但是,如果你试图改变下标的第一个维度,它就会爆炸。

答案 1 :(得分:4)

让我们仔细剖析一下,因为数组到指针的转换有时会令人困惑。

int arr[][3] = {{1, 2,}, {3, 4}, {5, 6}};

arr现在是一个包含3个整数的3个数组的数组。

int *pArr = *arr;

*arr在表达式中使用数组arr,因此它衰减到指向arr的第一个元素的指针 - 指向3个int数组的指针(包含{1,2,0}的数组)。取消引用该指针(使用*)可以得到3个整数的数组。现在你在表达式中使用那个数组,它衰减到指向int的指针,指向pArr。

(&pArr[0])[1] = 3;

pArr[0]给出pArr指向的整数(数字1)。 &pArr[0]指向该整数(实际上等于pArr)。使用[1]索引指针会引用数字1之后的下一个整数,即数字2.对于该引用,您将分配3.这是catch:指向数组元素的指针只能用于访问同一数组的其他元素。你的指针指向数组{1,2,0}的一个元素,你已经改为{1,3,0},这很好,但是

func(&pArr);

现在你正在创建一个指向int指针的指针(因为pArr是指向int的指针),并将其传递给你的函数。

ptr[0][1] = 5;

现在你已经使用了ptr[0],它计算了指向对象,这是你的原始指针pArr。这一行相当于pArr[1] = 5;,这仍然有效(将{1,2,0}数组更改为{1,5,0})。但是,ptr[1][...将无效,因为 ptr未指向任何类型的数组。它指向一个独立的指针。增加ptr将使其指向未初始化的内存并且取消引用将是未定义的行为。

还有其他问题:

你不应该写这个:

 int arr[] = { 1, 2, 3, 4, 5 };
 int *pArr = *arr;

数组arr衰减到指向int的指针(指向数字1),取消引用给出整数,并且不能将整数赋给指针pArr。 gcc说错误:从'int'无效转换为'int '*。 同样,你不能这样写:

int arr[][3] = {{1, 2,}, {3, 4}, {5, 6}};
int *pArr = **arr;

出于同样的原因:* arr是3个整数的数组{1,2,0},** arr是整数1,并且不能将整数赋给指针。

答案 2 :(得分:-1)

我发现C ++中的多维数组总是有点令人困惑,并且往往会避免它们。有几种解决方案更容易理解,例如Boost.MultiArray或Boost.UBlas库中的类,或矢量矢量,这取决于您的需求。