指向二维数组作为c中函数的参数

时间:2018-03-17 14:06:29

标签: c arrays pointers sudoku

我正在编写一个Sudoku求解程序,我对使用2D数组的指针感到有些困惑。目前我正在定义on,如此:

puzzle

然后我有一个名为int puzzle[9][9] = { {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0} }; 的函数,它将使用回溯来递归地解决这个问题。我需要将backtrack传递给puzzle,以便我可以在函数内修改它。目前backtrack看起来像

backtrack

但是gcc提出的错误是int backtrack(int (*p)[9][9]){ int puzzle[9][9] = *p; //actual logic is here return 0; } int puzzle[9][9] = *p;

我认为invalid initializer是指向int (*p)[9][9] int数组的指针,因此我应该可以通过解除引用9 x 9将其转换为int puzzle[9][9],但这似乎不起作用。

2 个答案:

答案 0 :(得分:1)

使用赋值表达式无法一次性分配给数组的所有元素,可以在定义数组时初始化数组的部分或全部元素。

1D数组衰减到指针。但是,2D数组不会衰减为指向指针的指针。

如果你这样声明backtrack

int backtrack(int arr[][9]);

甚至更好

int backtrack(int r, int c, int arr[][c]);

并打电话:

 int backtrack(puzzle);
 int backtrack(9,9, puzzle);

arr[x][y]元素的任何修改都会修改原始数组puzzle

arrbacktrack中的参数属于int (*)[c]类型。

编辑: 当然可以在调用函数中明确使用指针,如下所示:

#include <stdio.h>
#include <stdlib.h>

#define NR_OF_ROWS  9

void backtrack1(int nr_of_columns, int *array){
    // access to 
    // array[i][j] =
    // *(array + i*nr_of_columns + j)
}

void backtrack2(int nr_of_columns, int array[][nr_of_columns]){
    //...
}

int main(void)
{
    int nr_of_columns = 9;       // number of columns      
    int *ptr1;                   // (to show how to init a pointer to puzzle1)    
    int (*ptr2)[nr_of_columns];  // (to show how to init a pointer to puzzle2)   

    int puzzle1[NR_OF_ROWS][nr_of_columns]; // declare puzzle1 
    int puzzle2[NR_OF_ROWS][nr_of_columns]; // declare puzzle2 

    ptr1 = &puzzle1[0][0];       // pointer `ptr1` points to first element in the puzzle1
    ptr2 = puzzle2;              // pointer `ptr2` points to first element in the puzzle2

    // 1a.  call `backtrack1` function
    backtrack1(nr_of_columns, ptr1); // or  `backtrack1(nr_of_columns,  &table1[0][0]);`

    // 2a. call `backtrack2` function  
    backtrack2(nr_of_columns, ptr2); // or simply `backtrack2(nr_of_columns, table2);

    return 0;     
}

答案 1 :(得分:-2)

虽然参数声明是正确的但似乎你的意思是以下

int backtrack(int (*p)[9]){

并且函数被调用为

backtrack( puzzle );

当数组用作参数时,它会隐式转换为指向其第一个元素的指针。在数组puzzle的情况下,数组的第一个元素是第一个&#34;行&#34;这是int[9]类型的一维数组。

访问数组元素的语法如下所示

p[i][j]

其中ij是一些索引。

考虑到参数声明为

int backtrack(int p[9][9]){

然而编译器在任何情况下都会调整它,如

int backtrack(int (*p)[9]){

您可以声明参数

int backtrack(int (*p)[9][9] ){

但在这种情况下,该函数被称为

backtrack( &puzzle );

并且函数的主体太复杂了。例如,访问原始数组元素的语法类似于

( *p )[i][j]

此函数中的语句

int puzzle[9][9] = *p;

没有意义。您可能无法以这种方式初始化数组。我认为这个陈述在函数的实现中是多余的。你已经拥有指向第一个&#34;行&#34;的poinetr p。数组。您可以使用此指针更改原始数组或遍历其元素。实际上,数组的所有元素都通过指针p传递。