将2D数组传递给函数

IAE*_*IAE 2 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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

int arr[] = { 1, 2, 3, 4, 5 };
int *pArr = *arr;
Run Code Online (Sandbox Code Playgroud)

但为什么我不能写

int arr[][3] = {{1, 2,}, {3, 4}, {5, 6}};
int *pArr = **arr;
Run Code Online (Sandbox Code Playgroud)

甚至使用**pArr?

Bil*_*eal 6

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

究其原因在函数中下标是无效的,因为该功能无法确定什么阵列的尺寸的方式.使用单维数组,您不需要此信息 - 您只需将索引添加到给定的基指针.但是,对于二维数组,您需要维度来计算最终索引.

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看作是一个单维数组).但是,如果你试图改变下标的第一个维度,它就会爆炸.

  • 我已经低估了这个答案,因为答案和回答者关于衰变的评论都是错误的.`arr`不是指向内存的指针,但它本身就是一个内存块(如果它是一个指针,它就不需要衰减).它衰败到`int(*)[3]`,而不是`int*`.对于这个问题,我想说整个`(&pArr [0])[1]`就像`pArr [1]`一样.我怀疑他想写`(&pArr)[0] [1]`来模拟函数中的访问.但他的整个代码对我来说没有意义.我怀疑他很困惑.请更正答案,我将撤回我的downvote,队友. (2认同)