我已经知道将多维数组作为参数传递给函数的策略,即函数声明和定义中的参数必须包含列大小;但是行大小是无关的,可以省略。
但是我不知道原因。在做了一些研究之后,以下是我到目前为止的理解(如果不正确请纠正我!):
当将数组作为实参传递给函数时,无论维度形参如何,数组总是衰变成指向其第一个元素的指针。元素可以是另一个数组!对于二维数组,例如:int arr[3][4]
, arr是由三个int[4]
组成的数组,所以int[4]
是arr
的元素。因此,void foo(int a[3][4])
将衰变为void foo(int (*a)[4])
,它指向第一个int[4]
!
现在arr
指向第一个元素(假设地址是5000),这是第一个int[4]
,问题来了:编译器应该索引arr+1
的哪个地址?arr+1
的地址由COLUMN SIZE指定,它是:
5000 + 4(column size, int/column) * 4(bytes/int) = 5016!
所以,真正重要的是如何索引数组,而不是数组的大小!因此,除了最外层之外的维度都是必需的!
然而,我有一个问题,编译器如何知道数组在内存中的边界在哪里?对于上面的示例,没有行大小为3,编译器如何知道在
处停止5000 (arr [0] [0]) + 16 * (3 - 1) = 5032 (arr [2] [0])
而不是访问5048等等?或者在指定数组总大小的每个数据块之前有一些额外的位?
任何解释或帮助是感激的!非常感谢:)
必须包含列的大小;但行大小是无关的,可以被省略了。
对于数组访问,这是可以的,但是函数将不知道您是否在其边界之外访问数组。
将数组作为参数传递给函数时,不管是否维度参数,数组总是衰变成指向它的指针第一个元素。元素可以是另一个数组
数组只是一个连续的内存块。数组的数组是完全相同的。它将衰减为在数组内引用数组第一个元素的指针。只有类型不同,编译器会发出警告。
然而,我有一个问题,编译器如何知道在哪里数组在内存中的边界?对于上面的例子,没有行大小为3,编译器如何知道在
处停止?
编译器不知道,因为C不检查数组索引的限制。如果你访问数组外的元素,它会调用U定义Behavior