n 维(n>=2)数组在内存中如何表示?

发布于 2024-12-15 07:40:45 字数 393 浏览 0 评论 0原文

任何人都可以为我提供一个公式,以便我可以理解 n 维(n>=2)数组的内存表示,如下所示 “二维数组如何在内存中表示”

此计算仅适用于二维数组。

假设一个 5D 数组如何计算?

好吧....

我想我找到了答案:Array_data_struct#Two-Dimensional_arrays

Can anyone provide me with a formula so that I can understand the memory representation of an n-dimensional(n>=2) array like this "How_are_two-dimensional_arrays_represented_in_memory"?

This calculation is applicable for 2D-arrays only.

How to calculate, suppose, a 5D array?

Ok....

I think I found the answer: Array_data_structure#Two-dimensional_arrays

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

与他有关 2024-12-22 07:40:45

C 中的二维数组只不过是数组的数组。 3 维数组是数组的数组的数组。等等。

C99 标准的相关部分是 6.5 .2.1、“数组下标”:

连续的下标运算符指定a的一个元素
多维数组对象。如果 E 是一个 n 维数组
(n ≥ 2),维度为 i × j × 。 。 。 × k,然后 E(用作
除了左值之外)被转换为指向 (n -
1) 维度为 j × 的维数组。 。 。 × k。如果一元 *
运算符显式应用于此指针,或隐式地作为
下标的结果,结果是指向的 (n -
1)维数组,如果使用它本身会转换为指针
除了左值之外。由此可见,数组是存储的
按行优先顺序(最后一个下标变化最快)。

索引运算符是根据指针算术定义的这一事实引起了一些混乱。这并不意味着数组是“真正的指针”——事实上它们绝对不是。声明数组对象根本不会创建任何指针对象(当然除非它是指针数组)。但是引用数组的表达式通常(但并非总是)“衰减”为指向数组第一个元素的指针(这是一个指针,而不是指针对象) 。

现在,简单的数组对象,无论维度如何,都非常不灵活。在 C99 之前,所有数组对象都必须具有在编译时确定的固定大小。 C99 引入了可变长度数组 (VLA),但即便如此,VLA 的大小在声明时也是固定的(并且并非所有编译器都支持 VLA,即使在 C99 标准发布 12 年后也是如此)。

如果您需要更灵活的东西,常见的方法是声明一个指向元素类型的指针,然后使用 malloc() 分配一个数组并使指针指向数组的第一个元素:

int *ptr = malloc(N * sizeof *ptr);
if (ptr == NULL) /* handle allocation failure */

这使您可以使用与声明的固定大小数组对象相同的语法引用堆分配数组的元素,但在 arr[i] 中,表达式 arr 衰减到一个指针,而在ptr[i] `ptr已经是一个指针。

同样的事情可以扩展到更高的维度。您可以分配一个指针数组,然后初始化每个指针以指向所分配的数组的开头无论

这给你提供了一些行为非常类似于二维(或更多)数组的东西,但是你必须自己管理内存;这就是更大灵活性的代价。

严格来说,这不是二维数组。正如我上面所说,二维数组只是数组的数组。将其视为二维数组可能并非完全不合理,但这与 C 标准中的用法相冲突;它类似于将链表称为一维数组。

comp.lang.c FAQ 是一个很好的资源;第 6 节介绍了数组和指针,特别出色。

A 2-dimensional array in C is nothing more or less than an array of arrays. A 3-dimensional array is an array of arrays of arrays. And so on.

The relevant section from the C99 standard is 6.5.2.1, "Array subscripting":

Successive subscript operators designate an element of a
multidimensional array object. If E is an n-dimensional array
(n ≥ 2) with dimensions i × j × . . . × k, then E (used as
other than an lvalue) is converted to a pointer to an (n
1)-dimensional array with dimensions j × . . . × k. If the unary *
operator is applied to this pointer explicitly, or implicitly as a
result of subscripting, the result is the pointed-to (n
1)-dimensional array, which itself is converted into a pointer if used
as other than an lvalue. It follows from this that arrays are stored
in row-major order (last subscript varies fastest).

Some confusion is caused by the fact that the indexing operator is defined in terms of pointer arithmetic. This does not imply that arrays are "really pointers" -- and in fact they very definitely are not. Declaring an array object does not create any pointer objects at all (unless of course it's an array of pointers). But an expression that refers to the array usually (but not always) "decays" to a pointer to the array's first element (that's a pointer value, not a pointer object).

Now simple array objects, of however many dimensions, are quite inflexible. Prior to C99, all array objects had to be of a fixed size determined at compile time. C99 introduced variable-length arrays (VLAs), but even so a VLA's size is fixed when it's declared (and not all compilers support VLAs, even 12 years after the C99 standard was issued).

If you need something more flexible, a common approach is to declare a pointer to the element type, and then allocate an array using malloc() and have the pointer point to the array's first element:

int *ptr = malloc(N * sizeof *ptr);
if (ptr == NULL) /* handle allocation failure */

This lets you refer to elements of the heap-allocated array using the same syntax you'd use for a declared fixed-size array object, but in arr[i] the expression arr decays to a pointer, whereas in ptr[i] `ptr is already a pointer.

The same thing can be extended to higher dimensions. You can allocate an array of pointers, and then initialize each pointer to point to the beginning of an allocated array of whatever.

This gives you something that acts very much like a 2-dimensional (or more) array, but you have to manage the memory yourself; that's the price of the greater flexibility.

Strictly speaking, this is not a 2-dimensional array. A 2-dimensional array, as I said above, is only an array of arrays. It's probably not entirely unreasonable to think of it as a 2-D array, but that conflicts with the usage in the C Standard; it's similar to referring to a linked list as a 1-D array.

The comp.lang.c FAQ is a good resource; section 6, which covers arrays and pointers, is particularly excellent.

冷︶言冷语的世界 2024-12-22 07:40:45

二维数组实际上是指向数组的指针的数组。二维整数数组 a[i][j] 将占用 i*sizeof(int*) 作为指针数组,而 i* j*sizeof(int) 用于最终数组。

3-D 数组 a[i1][i2][i3] 是指向数组的指针数组的指针数组。第一层数组包含i1指针,第二层包含i1*i2指针,第三层包含i1*i2*i3整数。

一般来说,大小为 i1..iN 的 N 维数组将具有 N-1 层指针数组和 1 层整数数组。 N 级数组的长度为 iN,并且该级别中有 i1..iN-1 数组的乘积。

所以,一个 5 维数组:

1 array, length i1, of pointers
i1 arrays, length i2, of pointers
i1*i2 arrays, length i3, of pointers
i1*i2*i3 arrays, length i4, of pointers
i1*i2*i3*i4 arrays, length i5, of ints

希望有帮助(我希望我的索引是正确的)。

您发布的维基百科链接引用了/不同类型的多维数组/。默认情况下,C 多维数组就是我刚才描述的方式。您还可以将它们抽象为一维数组。这节省了内存并使整个数组连续,但它使访问元素变得更加复杂。对于 5 维示例:

// WARNING I AM CHANGING NOTATION. N1..N5 are the lengths in each direction.
// i1..i5 are the indicies.
int* bigarray = malloc(sizeof(int)*N1*N2*N3*N4*N5);
// now instead of bigarray[i1][i2][i3][i4][i5], write this:
*(bigarray + i1*N2*N3*N4*N5 + i2*N3*N4*N5 + i3*N4*N5 + i4*N5 + i5);

每个项都有一个偏移量乘以我们需要偏移的元素数。例如,要增加一个第一维度级别,我们需要遍历剩余的四个维度一次以“环绕”(如果您愿意的话)。

A 2 dimensional array is really an array of pointers to arrays. A 2-dimensional array of integers a[i][j] will take up i*sizeof(int*) for the array of pointers, and i*j*sizeof(int) for the final array.

A 3-D array a[i1][i2][i3] is an array of pointers to arrays of pointers to arrays. The first level of arrays contains i1 pointers, the second level contains i1*i2 pointers, the third level contains i1*i2*i3 integers.

In general, an N-dimensional array with sizes i1..iN will have N-1 levels of arrays of pointers and 1 level of arrays of ints. The arrays in level N have length iN and there are product of i1..iN-1 arrays in that level.

So, a 5-D array:

1 array, length i1, of pointers
i1 arrays, length i2, of pointers
i1*i2 arrays, length i3, of pointers
i1*i2*i3 arrays, length i4, of pointers
i1*i2*i3*i4 arrays, length i5, of ints

Hope that helps (and I hope I got the indices right).

That wikipedia link you posted refers to a /different kind of multidimensional array/. By default, C multidimensional arrays are the way I just described. You can also abstract them as a single dimensional array. This saves memory and makes the entire array contiguous, but it makes accessing elements somewhat more complex. For the 5-D example:

// WARNING I AM CHANGING NOTATION. N1..N5 are the lengths in each direction.
// i1..i5 are the indicies.
int* bigarray = malloc(sizeof(int)*N1*N2*N3*N4*N5);
// now instead of bigarray[i1][i2][i3][i4][i5], write this:
*(bigarray + i1*N2*N3*N4*N5 + i2*N3*N4*N5 + i3*N4*N5 + i4*N5 + i5);

each term there is an offset times the number of elements we need to offset. For example, to increment by one first-dimension level we need to traverse the the four remaining dimensions once to 'wrap around', if you will.

我不咬妳我踢妳 2024-12-22 07:40:45

我记得,C 语言中数组在内存中的存储方式尚未标准化。但有关数组以及它们如何存储在内存中的一些信息,请参阅以下两个链接:

http://webster.cs.ucr.edu/AoA/Windows/HTML/Arraysa2.html

http://publications.gbdirect.co.uk/c_book/chapter5/arrays.html

第一个链接更通用,讨论存储数组的不同方式,而第二个链接讨论 C 数组在内存中布局的最可能方式。

How arrays are stored in memory for C is not, as I recall, standardized. But for some information about arrays, and how they might be stored in memory, see the following two links:

http://webster.cs.ucr.edu/AoA/Windows/HTML/Arraysa2.html

http://publications.gbdirect.co.uk/c_book/chapter5/arrays.html

The first link is more general, and discusses different ways of storing arrays, while the second discusses the most likely way a C array may be layout in memory.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文