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

我一周前开始学习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]' 

为什么我不能像这样传递数组? 有没有更多方法可以通过它?

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

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

 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); 

当您将数组作为函数编写时,编译器将静默“调整”该数组并将其替换为指向第一个元素的指针。 所以当你编写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上使用[] ,这就是编译器告诉你的:“下标值既不是数组也不是指针,也不是矢量”。


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

void printField(int field[])情况下,由于上面提到的“数组调整”函数规则,这恰好起作用。 编译器不必知道数组大小,因为它只是用int*替换数组。

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

你可以做int field[][3] ,它会工作得很好。

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

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

使用pointeur比使用静态数组更好:)