【问题标题】:How to declare a jagged array in a header file?如何在头文件中声明锯齿状数组?
【发布时间】:2018-09-27 00:22:58
【问题描述】:

为了定义一个锯齿状数组,我使用@FaisalVasi 的this answer。这完美地工作。要获取此类已定义数组的 (i,j) 条目,请键入 (*jagged[i])[j]

但是,我喜欢将所有数组放在一个单独的文件中(我的常量数组),然后我必须在头文件中声明它们。而我无法做到这一点。我尝试了**jagged = unsigned[][]*jagged = unsigned*[],以及其他我不记得的尝试。无论如何,我尝试过的一切都没有奏效。那么我应该如何在头文件中声明锯齿状数组呢?

我是 C 的新手,我希望问题很清楚。否则请问我有什么可以澄清的。

【问题讨论】:

  • 我不记得我实际尝试了什么,你不仅要记住,还要在这里发布你的尝试。在头文件中定义数组似乎是您不想做的事情,除了 1. 如果您不知道自己在做什么,或者 2. 您真的知道自己在做什么'正在做。
  • 对不起@IharobAlAsimi,我表达得很糟糕。 我试过**jagged = unsigned[][]*jagged = unsigned*[],但我不记得我的其他尝试,如果有的话。

标签: c header-files jagged-arrays


【解决方案1】:

注意:偏离所请求的array-of-pointers-to-rows 语法并直接指向数组中的行,正如@Someprogrammerdude 所建议的,允许获得相同的结果,但是使用更少的间接性和更清晰的访问语法。

直接行数组解决方案

定义

unsigned jagged_row0[] = { 0, 1, 99 };
unsigned jagged_row1[] = { 1, 2, 3, 4, 5, 6, 99 };

unsigned *jagged[] = (unsigned *[]){ jagged_row0, jagged_row1 };

或一般来说:

type jagged_row0[] = { ... };
type jagged_row1[] = { ... };
...

type *jagged[] = (type *[]){ jagged_row0, jagged_row1, ... };

声明

extern unsigned *jagged[];

或一般来说:

extern type *jagged[];

用法

unsigned v_i_j = jagged[i][j];

或一般来说:

type v_i_j = jagged[i][j];

原答案

以下解决方案解决了@FaisalVasi 在cited answer 中给出的定义,其中锯齿状数组存储指向锯齿状行的显式指针。

定义(在某些 .c 文件中)

unsigned jagged_row0[] = {0,1};
unsigned jagged_row1[] = {1,2,3};

unsigned (*jagged[])[] = { &jagged_row0, &jagged_row1 }; /* note the ampersand */

/* or alternatively, since compound literals are lvalues ... */
unsigned (*jagged[])[] = { &(int[]){0,1}, &(int[]){1,2,3} };  

声明

extern unsigned (*jagged[])[];

用法

unsigned *jagged_row;
...
jagged_row = *jagged[i];
unsigned v_i_j = jagged_row[j];  /* value at [i][j] */

或更简洁:

unsigned v_i_j = (*jagged[i])[j];  /* value at [i][j] */

解释

锯齿行是一些基本类型的数组,在我们的例子中是一个无符号数组(长度由静态初始化决定)(unsigned[]),可以将其视为指向未签名 (unsigned *)。

根据建议的定义,锯齿状数组是指向锯齿状行的指针数组,同样简化后,可以将其视为unsigned ** 的数组。

当您索引第一个维度时,您将获得指向锯齿行(数组)的指针,然后您必须取消引用该指针以获取作为锯齿行的数组本身,而不是索引此数组达到最终值。

【讨论】:

  • 是的,extern unsigned (*jagged[])[]; 有效!谢谢!
  • 只有我觉得(*jagged[i])[j]丑吗?
  • @Stan 口味问题 :-) 它可以推广到 3D 锯齿状数组:我也有 (*(*special_pos[])[])[]。漂亮 ? ;-)
  • @StéphaneLaurent 好吧,如果你使用type ***jagged 并正确初始化jagged,你可以只使用jagged[i][j][k] 来引用一个单元格——我相信这在常识上要好得多。
【解决方案2】:

C 中的锯齿状数组通常是指向指针数组的第一个元素的指针。基本上是指向指针的指针。 IE。 type **jagged.

要在头文件中声明任何 变量,请使用extern 关键字。如

extern type **jagged;

[将type替换为实际类型]


有两种使用方式:

  1. 完全动态分配

    jagged = malloc(sizeof(*jagged) * M);
    for (unsigned i = 0; i < M; ++i)
        jagged[i] = calloc(N, sizeof(**jagged));
    
    // Now jagged is a MxN jagged matrix where each element is zero
    jagged[1][2] = 1;  // Sets a single value to 1
    
  2. 数组数组

    type jagged_row_0[] = { a, b, c };
    type jagged_row_1[] = { x, y };
    
    type **jagged = (type *[2]){ jagged_row_0, jagged_row_1 };
    
    printf("jagged[1][0] = %d\n", jagged[1][0]);
    

当然,您可以创建一个实际的指针数组(很像上面的第二种情况):

extern type *jagged[];

...

type *jagged[] = { jagged_row_0, jagged_row_1 };

...

printf("jagged[1][0] = %d\n", jagged[1][0]);

但是,当有不同大小的行时要非常小心,以免超出范围。

【讨论】:

  • 如果我这样做,编译时会出错:error: subscripted value is neither array nor pointer nor vector in (*jagged[i])[j]。这是我所有尝试时遇到的相同错误。也许(*jagged[i])[j] 不是获取 (i,j)-entry 的合适方法?
  • @StéphaneLaurent“矢量”?你真的用 C++ 编程吗?那么你应该使用std::vector
  • 不,这是 C,不是 C++(用 gcc 编译)。
  • @StéphaneLaurent 至于表达式(*jagged[i])[j] 想一想……jagged 是一个指向指针的指针。 jagged[i] 是一个指针。 *jagged[i]jagged[i] 指向的。换句话说,您尝试将 value 用作指针或数组。正确的方法就是jagged[i][j],当然要正确初始化。
  • @StéphaneLaurent gcc 前端程序也可以编译 C++ 文件。您的源文件名后缀是什么?是不是很简单.c
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 2013-11-07
  • 1970-01-01
  • 2021-11-07
  • 2020-04-02
相关资源
最近更新 更多