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

时间:2010-08-25 00:35:21

标签: c++ c arrays pointers

好的,我有一个静态分配的多维数组。我非常希望得到一个指向它的一部分的指针,并使用该指针访问其余部分。基本上,我希望能够做到这样的事情:

#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

此代码使用gcc:

导致此错误
t.c: In function ‘main’:
t.c:17: warning: initialization from incompatible pointer type

char**显然不是这里使用的正确类型。我假设这是因为静态分配的数组在内存中创建为单个块,而动态分配的数组在内存中分开,每个维度都有一个指向下一个的指针。

然而,正如你可能注意到的那样,这里的维度数量非常大,我显然需要使用实际变量来索引数组,而不是漂亮,纤细的字符0,所以它会变得痛苦long在实际代码中索引数组。我非常希望有一个指向数组的指针,以便访问数组的痛苦程度要小得多。但我无法弄清楚正确的语法 - 如果有的话。所以,任何帮助将不胜感激。感谢。

4 个答案:

答案 0 :(得分:4)

theArray[0][0]摆脱了前两个维度,因此您拥有char [DIM3][DIM4]类型的内容。当数组衰减到指针时,第一个维度将退出,因此您需要的声明是:

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

对于它的价值,gcc还会为您的数组声明显示警告:“警告:初始化程序周围缺少大括号”。静态变量和全局变量将自动初始化为0,因此您可以通过删除初始化程序来修复警告:

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

答案 1 :(得分:4)

给出声明

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

以下全部成立:

     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]      

因此,在您的情况下,ptr的类型必须为char (*)[DIM4]

答案 2 :(得分:1)

如果您使用的是Visual Studio,找到表达式类型的一种好方法是使用typeid。

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

打印

  

char(*)[8] [64]

但请注意,typeid()。name()的输出是特定于实现的行为,因此不能依赖它。但是通过打印一个更有意义的名字,VS在这方面恰好是好的

答案 3 :(得分:0)

无论是静态的,您的类型都不匹配

  

为什么双指针不能用作2D数组?

     

这是一个很好的例子,虽然编译器可能不会抱怨,    声明:“int ** mat”然后使用“mat”作为2D数组是错误的。    这是两种截然不同的数据类型,您可以使用它们进行访问    记忆中的不同位置。在一台好机器(例如VAX / VMS)上    错误以“内存访问冲突”错误中止程序。

     

这个错误很常见,因为很容易忘记腐烂    约定不得递归(不止一次)到    相同的数组,因此2D数组不等同于双指针。

     

“指向T指针”的指针不能作为“T的2D数组”。    2D数组与“指向T行的指针”“等效”,并且这个    与“指向T的指针”非常不同。

     

当一个双指针指向数组的第一个元素时,    与下标符号“ptr [0] [0]”一起使用,它被完全取消引用    两次(参见规则#5)。由此产生的两次完全解除引用    对象的地址等于INSIDE中找到的任何值    数组的第一个元素。由于第一个元素包含    我们的数据,我们将有疯狂的内存访问。   ...

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