此代码似乎正常工作
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 print2D(int ** ar,int r,int c)
{
for( int i = 0; i< r;i++)
for(int j = 0; j < c;j++)
cout<<ar[i][j]<<endl;
}
int main()
{
int ar2[1][2] = {{3,1}};
print2D(ar2,1,2);
return 0;
}
我不明白为什么这行不通?
答案 0 :(得分:3)
此数组int ar2[1][2]
实际上会衰减到int(*)[2]
。
没有分配指针的中间指针,有一个连续的1D数组可以以2D方式访问,因此剩下的[2]使步幅从一行移到另一行。
答案 1 :(得分:3)
问题出在内存地址的计算方式上。 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个元素,并且这将是一个不同的地址。那怎么知道?
该代码不起作用,因为它需要信息来计算地址,但没有该信息。
答案 2 :(得分:3)
二维数组被隐式转换为指向一维数组的指针,而不是指向指针的指针。
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;
}
也没有从指针到数组的指针(如上述示例)转换为指针的指针。
对于更大的尺寸,这也适用-除了必须在编译时知道除第一个尺寸外的所有尺寸。