c/c++语言开发共享为什么需要多维arrays中更高尺寸的尺寸范围?

根据post,

将2D数组传递给C ++函数

int array[10][10]; void passFunc(int a[][10]) // <---Notice 10 here { // ... } passFunc(array); 

为什么编译器内部观点需要更高的维度。

    另一种解释(数组到指针衰减):

    假设我们有一维数组,我们就像这样使用它:

     int array[10]; int i = array[3]; 

    编译器必须知道在哪里找到array[3] 。 它知道它需要跳过3个int才能到达array[3]那个array[3] 。 所以它有效。

    但是如果我们有一个二维数组,

     int array[2][5]; int i = array[1][1]; 

    为了让i在这里,编译器需要跳过多少个int ? 它需要跳过整行,再加上一行。 跳过一个很容易,因为我们知道一个int的大小。 但是我们还需要知道数组中行的大小 – 行的大小由类型的大小*每行的列数决定。 这是查看它的一种方式,这解释了为什么需要后一维度。

    让我们进一步将其作为一个小的脑筋急转弯

     int array[2][2][2]; int i = array[1][1][1]; 

    我们称之为尺寸X,Y,Z

    在这里,我们可以说我们有一个有限的int空间。 单位当然是一个int的大小。 行数由Y定义,平面数由Z定义。 这就是X作为基本单位,正如我们所说的那样,它是一个int的大小。 这三者的结合产生了一个“点”。

    为了能够到达3D空间中的任何点,我们需要知道每个维度“停止”的位置以及下一个维度的开始位置。 所以我们需要:

    所以, X已经给了我们,因为我们正在使用int 。 但我们不知道每架飞机的大小,也不知道有多少架飞机。 所以我们需要指定除第一维之外的所有维度。 这是一般规则。

    这也解释了为什么这个问题比仅仅指针衰减更精细的解释,因为一旦你达到2个以上的维度,你仍然需要知道它是如何工作的。 换句话说,您需要整体大小(维度的乘积)不溢出,并且您需要每个大小的维度能够使用连续的[]索引。

    C / C ++中的数组是一种类型,但不是第一类对象,它们在传递给函数时“衰减”为指向第一个元素的指针。

    int[10][10]是一个包含10个int[10]数组的数组……函数声明:

     void foo(int x[][10]); typedef int IntArray10[10]; void bar(IntArray10 *x); 

    对于编译器是相同的。

    将2d数组传递给函数时,您将传递指向第一个元素的指针(并忽略第一个维度),但元素本身是一个数组,编译器需要知道它的大小。

    与您在参数int a[][10]的“[]”所能想到的相反,该函数不采用二维数组而是指向一维数组的指针 – 其原型相当于

     void passFunc(int (*a)[10]) 

    array可以像所有数组一样衰减成指向其第一个元素的指针。
    像往常一样,该指针是&array[0] ,在这种情况下,它是一个指向带有十个int的数组的指针 – 一个int (*)[10]

    所以并不是你需要指定“更高维度”,而是参数是指向十个元素的数组而不是二维数组的指针。

    (你不能指向一个未指定大小的数组,因为编译器需要知道a[1]相对于a[0] ,即它需要知道sizeof(*a) 。)

    它是必需的,因为在C中不存在多维数组的概念。
    我们可以定义任何数组,甚至是另一个数组。 最后一个可以看作是一个多维数组。
    现在考虑将二维数组视为:

     int arrray[5][4]; 

    这将被解释为一个包含5个元素的数组,每个元素都是4个int的数组。
    在内存中,布局是顺序的:首先是第一个数组的4个元素,然后是第二个元素,依此类推,直到第4个元素的第5个数组。
    要访问第3个数组array[2][1]的第2个元素,编译器必须跳过前2个数组, 但这样做需要知道要跳过多少个元素
    即数学上第三个数组的第二个元素的地址是:

     //pElement2Array3 points the 2nd element of the 3rd array. //Note that 4 is the number of elements of the base dimension int *pElement2Array3 = &array[0] + (2 * 4) + 1; 

    (注意:术语(2 * 4) + 1不会乘以sizeof(int)因为这是通过指针算法自动完成的。)
    上面的数学运算由编译器在使用寻址array[2][1]时自动执行, 但要执行它,编译器必须知道基数组中有多少个元素(可能是数组数组的数组)。 。)

    简单地说,因为多维数组从右到左“增长”。 想想这样:

    int arr [a];a整数数组。

    int arr [b][a]a整数的b数组的数组。

    等等。

    至于为什么在将数组传递给函数时可以省略最左边的维度,这是因为“数组衰减”。 6.7.6.3/7说:

    将参数声明为”类型数组”应调整为”限定指向类型”

    也就是说,如果将一个函数参数声明为int param[10]int param[] ,它将被编译器静默/不可见地替换为指向int: int* param的指针,该指针指向数组的第一个元素。 数组本身仍然由调用者分配。

    它的工作原理是防止数组按值传递给函数,这将是非常无效的,并且在大多数情况下没有任何意义。

    现在对于多维数组的情况,适用上述相同的规则。 所以,如果你有int param[10][10]它会衰变成指向第一个元素的指针。 第一个元素是一个包含10个整数的数组,因此你得到一个指向 10个整数数组的数组指针int (*param)[10]

    如果你有int param[][10]会发生同样的情况,你仍然会得到一个int (*param)[10] 。 所以最左边的维度可以是任何东西 – 它无关紧要,因为它无论如何都会被忽略。

    但是最左边的其他维度是必需的,否则编译器将不知道数组将衰减到哪个指针类型。 在函数声明的特殊情况之外,没有int(*param)[]这样的东西,这意味着“指向未知大小的数组的数组指针”。

    作为函数参数int a[][10]等价于int (*a)[10] ,意思是: a是指向10 int数组的指针 。 在这种情况下,它不代表2Darrays。

    如果较高的维度留空,则编译器不可能知道指针a指向的数组的长度,并且不能执行指针运算。

      以上就是c/c++开发分享为什么需要多维arrays中更高尺寸的尺寸范围?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/560044.html

      (0)
      上一篇 2021年1月27日
      下一篇 2021年1月27日

      精彩推荐