【问题标题】:Syntax for pointer to portion of multi-dimensional statically-allocated array指向多维静态分配数组部分的指针的语法
【发布时间】:2010-08-25 10:18:02
【问题描述】:

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

#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 在实际代码中索引数组。我非常希望有一个指向要使用的数组的指针,这样访问数组就不会那么痛苦了。但我无法弄清楚正确的语法 - 如果有的话。因此,任何帮助将不胜感激。谢谢。

【问题讨论】:

    标签: c++ c arrays pointers


    【解决方案1】:

    theArray[0][0] 去掉了前两个维度,所以你有 char [DIM3][DIM4] 类型的东西。当数组衰减为指针时,第一个维度将丢失,因此您想要的声明是:

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

    对于它的价值,gcc 还会为您的数组声明显示一个警告:“警告:初始化器周围缺少大括号”。静态变量和全局变量会自动初始化为 0,所以你可以去掉初始化器来修复警告:

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

    【讨论】:

    • 与其说是“全局范围的变量”,不如说是“具有静态存储持续时间的变量”(其中“全局范围的变量”是一个子集)。
    • 好点,更新的答案,虽然试图避免使用标准语言。
    【解决方案2】:

    给定一个声明

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

    以下都成立:

    表达式类型衰减到 ---------- ---- --------- 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]

    【讨论】:

      【解决方案3】:

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

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

      打印出来的

      字符 (*)[8][64]

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

      【讨论】:

        【解决方案4】:

        不管它是静态的,你的类型不匹配

        为什么双指针不能用作二维数组?

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

        这个错误很常见,因为很容易忘记衰变 约定不能递归(不止一次)应用于 相同的数组,所以二维数组不等同于双指针。

        “指向 T 指针的指针”不能用作“T 的二维数组”。 二维数组“等价于”“指向 T 行的指针”,而这 与“指向 T 的指针”有很大不同。

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

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

        【讨论】:

          猜你喜欢
          • 2022-01-14
          • 2011-04-23
          • 2013-03-07
          • 2013-05-26
          • 2016-04-19
          • 2020-08-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多