【问题标题】:Jagged Array in C (3D)C(3D)中的锯齿状数组
【发布时间】:2011-06-10 07:06:40
【问题描述】:

我该怎么做?

double layer1[][3] = {
    {0.1,0.1,0.8},
    {0.1,0.1,0.8},
    {0.1,0.1,0.8},
    {0.1,0.1,0.8}
};
double layer2[][5] = {
    {0.1,0.1,0.1,0.1,0.8}
};
double *upper[] = {layer1, layer2};

在尝试不同的想法后,我阅读了以下内容;无济于事。 Do jagged arrays exist in C/C++?

我理解(我希望)

double **upper[] = {layer1, layer2};

与我想要的类似,但由于图层不是指针数组,因此无法正常工作。我故意使用 C。


我正在尝试避免这样做(这可行)。

double l10[] = {0.1,0.1,0.8};
//l11 etc
double *l1[] = {l10,l11,l12,l13};
double l20[] = {0.1,0.1,0.1,0.1,0.8};
double *l2[] = {l20};

double **both[] = {l1, l2};

【问题讨论】:

  • 你声称这是 C,但你使用的是 cout
  • 习惯原因,无关 - 已修复

标签: c arrays pointers stack jagged-arrays


【解决方案1】:

在现代 C 中,有一个名为 compound literal 的工具可以至少部分实现您想要的:

double (*(layer1[])) = {
  (double[]){0.1,0.1,0.8},
  (double[]){0.1,0.1,0.8},
  (double[]){0.1,0.1,0.8},
  (double[]){0.1,0.1,0.8}
};
double (*(layer2[])) = {
    (double[]){0.1,0.1,0.1,0.1,0.8}
};
double (*(*(upper[]))) = {layer1, layer2};

我已将() 添加到类型中,以向您展示类型的绑定规则。但请注意,使用这种类型的编程,您总是必须自己记住数组边界。

编辑: (double[]){ 0.0 } 的构造称为复合文字,其效果与您在第二个版本中声明的临时数组相同。优点是您不必为它们发明命名约定,访问这些临时变量的唯一方法是通过更大的数组。也许将const 放入所有这些会更好,这样您就不会意外更改指针:

double (*const(layer1[])) = {
  (double[]){0.1,0.1,0.8},
  (double[]){0.1,0.1,0.8},
  (double[]){0.1,0.1,0.8},
  (double[]){0.1,0.1,0.8}
};
double (*const(layer2[])) = {
    (double[]){0.1,0.1,0.1,0.1,0.8}
};
double (*const(*const(upper[]))) = {layer1, layer2};

这仍然可以让您更改内容(所有doubles),但不能更改指针。如果您知道doubles 本身在整个程序中不会更改,请将double 更改为double const

【讨论】:

  • 感谢您的回答,它适用于非常具体的应用程序,并且在编译时始终知道边界并存储在常量中。请问 (double[]) 实际上是如何影响数组的处理方式的?
  • @Daniel:例如layer1 不再是 double[][3] 类型,它现在是`double *[]. i.e. it's an array of pointers to double. sizeof` 类型现在会以不同的方式工作,例如。
【解决方案2】:
struct {
  size_t length;
  size_t stride;
  double *data;
} upper = {
  {
    sizeof(layer1) / sizeof(layer1[0]),
    sizeof(layer1[0]) / sizeof(layer1[0][0]),
    (double *)layer1,
  },
  {
    sizeof(layer2) / sizeof(layer2[0]),
    sizeof(layer2[0]) / sizeof(layer2[0][0]),
    (double *)layer2,
  },
};

int i, j, k;
for (i = 0; i < sizeof(upper) / sizeof(upper[0]); i++) {
  for (j = 0; j < upper[i].length; j++) {
    for (k = 0; i < upper[i].stride; k++)
      printf(" %d" + !k, upper[i].data[upper[i].stride * j + k]);
    printf("\n");
  }
  printf("\n");
}

您必须意识到,C 中的多维数组只是以行为主打包到线性存储中。实际尺寸仅在编译时由类型知道:它们在运行时的数据中找不到。

【讨论】:

    【解决方案3】:

    Layer1 和 Layer2 是指针数组,根据锯齿状数组的定义。 没有理由

    double ** upper[] = {layer1, layer2}
    

    不工作。如果没有,请发布错误消息。

    唯一的问题是您的数组会衰减为指针。如果这对您来说是个问题,您需要使用 C99 并阅读您已经提到的线程中的this post

    【讨论】:

    • 不,它们不是,数组 layer1,layer2 是非常定义的数组数组。 (下面显示的错误,感谢 ehemient)
    • 不起作用。 layer1 的类型为 double[4][3](衰减为 double*[3],而不是 double**),layer2 也是如此。
    • 在 C 中,数组和 a 指针之间几乎没有明确的区别(有区别,但在这里解释它们还很远)但我必须说我自己没有测试过,是时候启动旧的编译器 :)
    • 我明白,但这里没有明确声明指针,因此您发布的内容不起作用。无论如何,据我所知。
    • Jens 的帖子完美表达了我的意思,给他投票吧 :)
    猜你喜欢
    • 1970-01-01
    • 2015-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-27
    • 2016-12-20
    • 2014-01-23
    相关资源
    最近更新 更多