将2D数组传递给C语言的方法

时间:2016-11-10 07:45:30

标签: c arrays

一周前我开始学习C语言。 为了测试,我决定写一个tictactoe游戏。

我有一个领域。

int field[3][3];

一个函数printField

void printField(int field[3][3]){
for(int i = 0; i < 3; i++){
    for(int j = 0; j < 3; j++){
        printf("%i", field[i][j]);
    }
    printf("\n");
}}

它的主要工作是这样的:

int main(){
printField(field);}

但如果我改变

 void printField(int field){...}

void printField(int field[][]){...}

它给了我一堆错误:

subscripted value is neither array nor pointer nor vector                      
passing argument 1 of ‘printField’ makes integer from pointer without a cast
note: expected ‘int’ but argument is of type ‘int (*)[3]’

为什么我不能像这样传递数组? 还有其他方法可以通过吗?

3 个答案:

答案 0 :(得分:2)

该功能独立于对该功能的任何调用。因此该函数无法从程序的其余部分猜测数组大小。在函数体中,您必须有常量或变量来表示所有维度。

您可以为此使用变量而不是固定大小:

void printField(int r, int c, int field[r][c])
{
    for(int i = 0; i < r; i++)
        for(int j = 0; j < c; j++)
            printf("%i", field[i][j]);

    printf("\n");
}

并调用该函数:

printField(3, 3, field);

您可以从数组名称计算尺寸。使用宏限制了丑陋的语法:

#define printField(a) printField( sizeof(a)/sizeof((a)[0]), sizeof((a)[0]) / sizeof((a)[0][0]), (a) )

int f1[3][3] = { 0 };
printField(f1);

int f2[4][5] = { 0 };
printField(f2);

答案 1 :(得分:0)

当您将数组作为函数编写时,编译器将默默地&#34;调整&#34;该数组并用指向第一个元素的指针替换它。因此,当您编写void func (int x[3])时,编译器会默默地将其替换为void func (int* x),其中指针指向数组的第一项。

以这种方式设计C的原因并不是避免大型数组被推入堆栈,这将是缓慢且耗费内存的。

在您的情况下,函数void printField(int field[3][3])会在

行后面进行静默调整
void printField(int (*field)[3])

是指向第一个元素的数组指针,它是一个int[3]数组。哪个仍然可以用作field[i][j],所以一切都很好。你可以假装它是函数内部的一个数组。

void printField(int field)显然没有任何意义。这不是一个数组而只是一个项目。你不能在普通的int上使用[]以及编译器告诉你的内容:&#34;下标的值既不是数组也不是指针,也不是矢量&#34;。

void printField(int field[][]){...}也不起作用,因为空[]表示&#34;声明一个不完整类型的数组&#34;。在定义数组大小之前无法使用它。

void printField(int field[])的情况下,由于上面提到的&#34;数组调整&#34;功能规则。编译器不必知道数组大小,因为它只是用int*替换了数组。

但是在具有两个未知维度的情况下,编译器会尝试将int field[][]调整为int (*field)[]。这是一个指向不完整类型数组的指针,不能被函数使用。

但你可以int field[][3],它会正常工作。

答案 2 :(得分:-4)

在C中您可以像这样传递数组

void printField(int **field){...}

使用pointeur比使用静态数组要好得多:)