如果我有这样的多维数组:
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是:指向多维数组的指针类型的语法如何。
在我的解决方案代码中已经可以看到答案。这就是全部,继续前进,没有什么可看的;)不过感谢回复。
答案 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];
,其中x
和y
与前一个示例相同,而m
是大小一排。
我还建议您将二维数组的行号和列号存储到结构中。