C++ 为什么可以';我将2D数组作为指针传递给指针,但可以将1D数组作为指针传递

C++ 为什么可以';我将2D数组作为指针传递给指针,但可以将1D数组作为指针传递,c++,arrays,pointers,multidimensional-array,C++,Arrays,Pointers,Multidimensional Array,显然,这个代码是有效的 void printD(int * ar,int r) { for(int i = 0; i < r; i++) cout<<ar[i]<<endl; } int main() { int ar[3] = {1,2,3}; printD(ar,3); return 0; } void printD(int*ar,int-r) { 对于(int i=0;i)。如果

显然,这个代码是有效的

void printD(int * ar,int r)
    {
        for(int i = 0; i < r; i++)
            cout<<ar[i]<<endl;
    }
int main()
{
    int ar[3] = {1,2,3};
    printD(ar,3);
    return 0;
}
void printD(int*ar,int-r)
{
对于(int i=0;icout这个数组
intar2[1][2]
实际上衰减为
int(*)[2]


没有指向分配的指针的中间指针,有一个连续的1D数组,可以在2D中访问,因此剩余的[2]提供了从一行到另一行的步幅。

此数组
int ar2[1][2]
实际上衰减为
int(*)[2]


没有中间指针指向分配的指针,有一个连续的1D数组,可以在2D中访问,因此剩余的[2]使跨距从一行到另一行。

问题在于如何计算内存地址。
a[0]
是第一个元素,而
a[1]
是第二个元素,因此
a[1]
的地址是
a[0]
的位置加上元素的大小。这里没有问题,任何元素的地址都可以通过第一个元素的位置乘以偏移量乘以元素大小来计算

这是如何处理多维数组的?a[0][5]
和a[1][5]之间的距离是多少?这取决于行的大小(为了这个示例,我使用这个术语,实际上没有任何“行”),因为最后它只是一个内存块。如果一行有10个元素,那么距离是元素大小的10倍。因此,该行大小很重要,没有它就无法计算元素在数组中的确切位置。现在,使用以下内容:

void print2D(int ** ar,int r,int c)
它怎么知道行的大小呢?
ar[1][0]
是第二行的第一个元素,所以如果一行的大小为10,那么这将是内存块中的第十个元素。但是,如果行的大小为20,那么它将是第20个元素,这将是一个不同的地址。那么它怎么知道呢


代码不起作用,因为它需要信息来计算地址,但它没有这些信息。

问题在于如何计算内存地址。
a[0]
是第一个元素,
a[1]
是第二个元素,因此
a[1]
的地址是
a[0]的位置
加上元素的大小。这里没有问题,任何元素的地址都可以通过第一个元素的位置乘以偏移量乘以元素大小来计算

这是如何处理多维数组的?a[0][5]和a[1][5]之间的距离是多少?这取决于行的大小(为了这个示例,我使用这个术语,实际上没有任何“行”),因为最后它只是一个内存块。如果一行有10个元素,那么距离是元素大小的10倍。因此,该行大小很重要,没有它就无法计算元素在数组中的确切位置。现在,使用以下内容:

void print2D(int ** ar,int r,int c)
它怎么知道行的大小呢?
ar[1][0]
是第二行的第一个元素,所以如果一行的大小为10,那么这将是内存块中的第十个元素。但是,如果行的大小为20,那么它将是第20个元素,这将是一个不同的地址。那么它怎么知道呢


代码不起作用,因为它需要信息来计算地址,但它没有这些信息。

二维数组隐式转换为指向一维数组的指针,而不是指向指针的指针

void print2D(int (*ar)[2],int r,int c)
{
     //  definition omitted for brevity
}
int main()
{

   int ar2[1][2] = {{3,1}};
   print2D(ar2,1,2);
   return 0;
}
也没有从指向数组的指针(如上面的示例)转换为指向指针的指针


对于更多维度,这同样有效-除了第一个维度以外的所有维度必须在编译时已知。

二维数组隐式转换为指向一维数组的指针,而不是指向指针的指针

void print2D(int (*ar)[2],int r,int c)
{
     //  definition omitted for brevity
}
int main()
{

   int ar2[1][2] = {{3,1}};
   print2D(ar2,1,2);
   return 0;
}
也没有从指向数组的指针(如上面的示例)转换为指向指针的指针


对于更多的维度,这也可以工作,除了在编译时必须知道第一个以外的所有维度。

二维数组不是指针的指针。它是指向2D数组的指针。这是比C++更大的C代码(除了<代码> cOUT <代码> >)。如果你真的想用C++,你应该考虑使用标准容器。(
std::vector
)。并传递引用。在KR C语言的旧时代,我们经常使用诸如int ar2[2][2]={{3,1},{2,4};print1D((int*)ar2,4);不向孩子们显示,但它正在工作……最好定义自己的矩阵类型,或者使用一个库。前一个可怕的例子有助于理解为什么
ar[2](2)< /Cord>不是一个<代码> int *>代码>。一个2D数组不是指针的指针。它是一个指向2D数组的指针。这是比C++更大的C代码(除了<代码> cOUT <代码> >之外。如果你真的想用C++,你应该考虑使用标准容器(<代码> STD::vector < /代码>)在KR C语言的旧时代,我们经常使用一些可怕的东西,比如int ar2[2][2]={{3,1},{2,4};print1D((int*)ar2,4);不向孩子们展示,但它在工作……最好定义你自己的矩阵类型,或者使用一个库。前一个可怕的例子有助于理解为什么
ar[2][2]
不是
int**