简体   繁体   English

指向多维静态分配数组部分的指针的语法

[英]Syntax for pointer to portion of multi-dimensional statically-allocated array

Okay, I have a multi-dimensional array which is statically-allocated. 好的,我有一个静态分配的多维数组。 I'd very much like to get a pointer to a portion of it and use that pointer to access the rest of it. 我非常想获得指向它一部分的指针,并使用该指针来访问它的其余部分。 Basically, I'd like to be able to do something like this: 基本上,我希望能够执行以下操作:

#include <stdio.h>
#include <string.h>

#define DIM1 4
#define DIM2 4
#define DIM3 8
#define DIM4 64

static char theArray[DIM1][DIM2][DIM3][DIM4] = {0};

int main()
{
    strcpy(theArray[0][0][0], "hello world");

    char** ptr = theArray[0][0];

    printf("%s\n", ptr[0]);

    return 0;
}s

This code results in this error using gcc: 此代码使用gcc导致此错误:

t.c: In function ‘main’:
t.c:17: warning: initialization from incompatible pointer type

char** is apparently not the correct type to use here. char**显然不是此处使用的正确类型。 I assume it's because statically-allocated arrays are created as a single block in memory while dynamically allocated ones are separated in memory, with each dimension having a pointer to the next one. 我认为这是因为静态分配的数组在内存中创建为单个块,而动态分配的数组在内存中分离,每个维都有指向下一个的指针。

However, as you likely noticed, the number of dimensions here is painfully large, and I'm obviously going to need to use actual variables to index the array rather than the nice, slim character 0, so it's going to get painfully long to index the array in actual code. 但是,您可能已经注意到,这里的维数非常大,我显然需要使用实际变量来对数组进行索引,而不是使用漂亮的苗条字符0,因此要很长时间才能进行索引实际代码中的数组。 I'd very much like to have a pointer into the array to use so that accessing the array is much less painful. 我非常想在数组中使用一个指针,这样访问数组就不会那么麻烦了。 But I can't figure out the correct syntax - if there even is any. 但是我无法弄清楚正确的语法-如果有的话。 So, any help would be appreciated. 因此,任何帮助将不胜感激。 Thanks. 谢谢。

theArray[0][0] gets rid of the first two dimensions, so you have something of type char [DIM3][DIM4] . theArray[0][0]摆脱了前两个维度,因此您具有类型为char [DIM3][DIM4] The first dimension will drop out when the array decays to a pointer, so the declaration you want is: 当数组衰减为指针时,第一个维度将丢失,因此所需的声明为:

char (*ptr)[DIM4] = theArray[0][0];

For what it's worth, gcc also displays a warning for your array declaration: "warning: missing braces around initializer". 对于它的价值,gcc还会为您的数组声明显示警告:“警告:初始化程序周围缺少括号”。 Static variables and global variables will automatically be initialized to 0, so you can fix the warning by getting rid of the initializer: 静态变量和全局变量将自动初始化为0,因此您可以通过取消初始化程序来修复警告:

static char theArray[DIM1][DIM2][DIM3][DIM4];

Given a declaration 给出声明

T arr[J][K][L][M];

the following all hold: 以下全部成立:

Expression            Type                    Decays to
     ----------            ----                    ---------
            arr            T [J][K][L][M]          T (*)[K][L][M]
           &arr            T (*)[J][K][L][M]
         arr[j]            T [K][L][M]             T (*)[L][M]
        &arr[j]            T (*)[K][L][M]
      arr[j][k]            T [L][M]                T (*)[M];
     &arr[j][k]            T (*)[L][M] 
   arr[j][k][l]            T [M]                   T *
  &arr[j][k][l]            T (*)[M]

So, in your case, the type of ptr needs to be char (*)[DIM4] . 因此,在您的情况下, ptr的类型必须为char (*)[DIM4]

If you are using Visual Studio, a nice way to find out the type of the expression is to use typeid. 如果使用的是Visual Studio,查找表达式类型的一种好方法是使用typeid。

 cout << typeid(&theArray[0][0]).name(); 

which prints 哪个打印

char (*)[8][64] 字符(*)[8] [64]

But note that output of typeid().name() is an implementation specific behavior and as such can not be relied upon. 但是请注意,typeid()。name()的输出是特定于实现的行为,因此不能依赖。 But VS happens to be nice in this regards by printing a more meaningful name 但是VS在这方面碰巧是不错的,它可以打印一个更有意义的名称

Does not matter that it is static, your types don't match 没关系,它是静态的,您的类型不匹配

Why a double pointer can't be used as a 2D array? 为什么不能将双指针用作2D数组?

This is a good example, although the compiler may not complain, it is wrong to declare: "int **mat" and then use "mat" as a 2D array. 这是一个很好的例子,尽管编译器可能不会抱怨,但是声明“ int ** mat”然后将“ mat”用作2D数组是错误的。 These are two very different data-types and using them you access different locations in memory. 这是两种非常不同的数据类型,使用它们可以访问内存中的不同位置。 On a good machine (eg VAX/VMS) this mistake aborts the program with a "memory access violation" error. 在良好的计算机(例如VAX / VMS)上,此错误会中止程序,并显示“内存访问冲突”错误。

This mistake is common because it is easy to forget that the decay convention mustn't be applied recursively (more than once) to the same array, so a 2D array is NOT equivalent to a double pointer. 这个错误很常见,因为很容易忘记不要将衰减约定递归地(多次)应用于同一数组,因此2D数组不等同于双指针。

A "pointer to pointer of T" can't serve as a "2D array of T". “指向T的指针”不能用作“ T的2D数组”。 The 2D array is "equivalent" to a "pointer to row of T", and this is very different from "pointer to pointer of T". 2D数组与“指向T行的指针”“等效”,这与“指向T行的指针”非常不同。

When a double pointer that points to the first element of an array, is used with subscript notation "ptr[0][0]", it is fully dereferenced two times (see rule #5). 当使用指向下标符号“ ptr [0] [0]”的双指针指向数组的第一个元素时,它将被完全取消引用两次(请参阅规则5)。 After two full dereferencings the resulting object will have an address equal to whatever value was found INSIDE the first element of the array. 经过两次完全解引用后,所得对象的地址将等于在数组的第一个元素内找到的任何值。 Since the first element contains our data, we would have wild memory accesses. 由于第一个元素包含我们的数据,因此我们将拥有野生内存访问权限。 ... ...

etc.... http://www.ibiblio.org/pub/languages/fortran/append-c.html 等等... http://www.ibiblio.org/pub/languages/fortran/append-c.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM