c中结构中的多维数组引用

时间:2017-09-03 17:54:32

标签: c arrays pointers struct reference

如果我有这样的多维数组:

int arr2d[2][3] = {{0,1,2}, {10,11,12}};

我可以将它传递给这样的函数:

void foobar(int arg[][3])

这不是按值调用,这是通过引用调用,所以只是一个指向起始地址的指针,但编译器仍然知道它是一个2D数组,并且我能够像访问它一样访问它功能

现在结构中的工作原理如何?

typedef struct {
  int arr2d[][3];
} Foobar_t

首先,这给了我:error: flexible array member in otherwise empty struct。我可以通过这样做来解决这个问题:

typedef struct {
  int dummy;
  int arr2d[][3];
} Foobar_t

它将编译时没有错误或警告。但是当我尝试像Foobar_t foobar = {1337, arr2d}那样使用它时,我收到了一些警告:

missing braces around initializer
initialization makes integer from pointer without a cast

访问时:subscripted value is neither array nor pointer nor vector

一维数组很容易被视为指针。但对于多维数组,编译器需要知道不同维度的大小才能正确计算偏移量。有没有强制转换(int (*)[3])的方法,为什么语法与函数参数不同?

所以这是我想要避免的解决方法:

#include <stdio.h>

static int testArr[2][3] = {{0,1,2},{10,11,12}};

typedef struct {
  int *arr2d;
} Foobar_t;


int main( int argc, char** argv ) {
  Foobar_t foobar = {(int*)testArr};
  int (*arr2d)[3] = (int (*)[3]) foobar.arr2d;
  printf("testStruct_0_0: %d\n", arr2d[0][0]);
  printf("testStruct_1_0: %d\n", arr2d[1][0]);

  return 1337;
}

编辑:

有些评论表明参考不是正确的词。当然在C语言中,这是通过指针实现的。 因此,这个问题的TLDR是:指向多维数组的指针类型的语法如何。

在我的解决方案代码中已经可以看到答案。这就是全部,继续前进,没有什么可看的;)不过感谢回复。

3 个答案:

答案 0 :(得分:1)

没有&#34;通过引用呼叫&#34;在C语言中。函数参数始终按值传递。数组看起来很特殊,因为数组在大多数表达式(包括函数调用)中衰减为指向其第一个元素的指针。这意味着当一个数组在函数调用中用作参数时,指向第一个元素的指针将传递给函数而不是数组;但它是传递的指针的值。

在函数声明符中,数组类型被调整为指向适当类型的指针。这特定于函数声明符的语义。因此,函数声明如:

void foobar(int arg[][3]);
调整

以将指向三个int s的数组的指针作为参数:

void foobar(int (*arg)[3]);

通常,类型表达式(例如int arg[][3])是不完整类型,因为如果没有更多信息,则无法知道数组arg[][]的大小。

C中的结构不允许使用不完整类型指定成员类型(有一个例外),因为没有这些信息就无法知道struct的大小。此外,struct说明符不会对函数声明符所做的数组类型进行相同的调整,因为struct实际上可能包含数组成员。

struct中不完整类型规则的例外情况是灵活数组成员。具有至少两个命名成员的struct的最后一个成员可能具有不完整的数组类型。

问题中问题的简单解决方案是更改struct的说明符以使用指向数组的指针。请注意,此处成员.arr2d不是数组,而是指向三个int的数组的指针:

typedef struct {
  int (*arr2d)[3];
} Foobar_t;

答案 1 :(得分:0)

结果只是看着解决方案向我展示了解决方案:

typedef struct {
  int (*arr2d)[3];
} Foobar_t;

这是指向2D数组的指针的正确类型。 type (*name)[n]也适用于函数参数。

那么为什么其他语法type name[][n]仍然对函数参数有效?可能与结构的灵活数组特征的冲突使它无法在那里工作。

答案 2 :(得分:0)

您可以尝试使用int **arr2d,这样您就可以通过arr2d[x][y]访问它,或者只是将其转换为像int *arr2d = malloc(2*3*sizeof(int));这样的一维数组。 这样,您就需要访问以下值:arr2d[x*m + y];,其中xy与前一个示例相同,而m是大小一排。

我还建议您将二维数组的行号和列号存储到结构中。