[英]Doesn't a 2D array decay to pointer to pointer
到目前为止,我几乎可以肯定
int arr[4][5];
然后, arr
将衰减为指向指针的指针。
我不确定如何将arr
指针,但对我来说似乎很明显。 因为arr[i]
将是一个指针,因此arr
应该是一个指向指针的指针。
我错过了什么吗?
是的,您错过了很多:)
为了避免出现其他问题,我将链接到我今天早些时候写的一个答案 , 该答案解释了多维数组。
考虑到这一点, arr
是具有4个元素的一维数组,每个元素都是5个int
s的数组。 当在&arr
或sizeof arr
以外的表达式中使用时,它衰减为&arr[0]
。 但是&arr[0]
什么? 它是一个指针,重要的是一个右值。
由于&arr[0]
是指针,因此它不能进一步衰减。 (数组衰减,指针不衰减)。 此外,这是一个右值。 即使它可以衰减为指针,该指针将指向何处? 您不能指向右值。 (什么是&(x+y)
?)
另一种看待它的方法是记住int arr[4][5];
是一个20 int
的连续块,在编译器的脑海中分为4批,每批5批,但是在运行时内存中没有特殊标记。
如果存在“双重衰减”,则int **
指向什么? 根据定义,它必须指向一个int *
。 但是int *
在内存中的什么位置? 为了防止这种情况的发生,内存中肯定不会挂满一堆指针。
一个简单的规则是:
出现在表达式中的对T型数组对象的引用衰减(除三个例外)为指向其第一个元素的指针 ; 结果指针的类型是T指针。
处理一维数组时,数组名称在传递给函数时会转换为指向第一个元素的指针。
2D数组可以看作是数组的数组 。 在这种情况下, int arr[4][5];
,您可以将arr[]
视为数组名,并在传递给函数时将其转换为指向数组arr
的第一个元素的指针。 由于arr
第一个元素是一个数组,所以arr[i]
是指向该数组第i
行的指针,并且是指向5个int
s数组的指针 。
通常,将2维数组实现为指针数组(在某种意义上,它是指向指针的指针...指向数组中第一个元素(即指针)的指针)。第一个索引(即arr[x]
),它索引到指针数组,并将指针提供给第x
行。 第二个索引(即arr[x][y]
)给出该行中的第y
int
。
对于静态声明的数组(如您的示例),实际存储空间被分配为单个块...在您的示例中,分配为20个整数(在大多数平台上为80个字节)的单个连续块。 在这种情况下,没有指针数组,编译器只是执行适当的算法以解决数组的正确元素。 具体来说, arr[x][y]
等于*(arr + x * 5 + y)
。 这种自动调整的算法仅在数组的原始范围内发生...如果将数组传递给函数,则维信息将丢失(就像1维数组的维丢失一样),并且显式地进行数组索引计算。
为了避免这种情况,请不要将数组声明为静态数组,而是声明为指针数组,每个指针都指向1维数组,例如本例:
int arr0[5];
int arr1[5];
int arr2[5];
int arr3[5];
int* arr[4] = { arr0, arr1, arr2, arr3 };
然后,将arr
传递给函数时,也可以将其作为函数中的2维数组进行寻址。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.