指向2D数组作为c函数中的参数的指针

指向2D数组作为c函数中的参数的指针,c,arrays,pointers,sudoku,C,Arrays,Pointers,Sudoku,我正在写一个数独解题程序,我对使用2D数组的指针有点困惑。目前,我正在定义这样一个谜题: 然后我有一个叫做backtrack的函数,它将使用backtrack递归地解决这个问题。我需要将谜题传递到回溯,以便在函数内部修改它。当前回溯看起来像 int backtrack(int (*p)[9][9]){ int puzzle[9][9] = *p; //actual logic is here return 0; } 但是gcc给出了一个错误,指出int-puzzle

我正在写一个数独解题程序,我对使用2D数组的指针有点困惑。目前,我正在定义这样一个谜题:

然后我有一个叫做backtrack的函数,它将使用backtrack递归地解决这个问题。我需要将谜题传递到回溯,以便在函数内部修改它。当前回溯看起来像

int backtrack(int (*p)[9][9]){
    int puzzle[9][9] = *p;

    //actual logic is here

    return 0;
}
但是gcc给出了一个错误,指出int-puzzle[9][9]=*p;是无效的初始值设定项


我的印象是int*p[9][9]是一个指向9 x 9 int数组的指针,因此我应该能够通过取消对p的引用将其转化为一个int谜题[9][9],但这似乎不起作用。

虽然参数声明是正确的,但您的意思似乎是

int backtrack(int (*p)[9]){
这个函数被称为like

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

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

p[i][j]
( *p )[i][j]
其中i和j是一些指数

考虑到当参数声明为

int backtrack(int p[9][9]){
然而,编译器在任何情况下都会对其进行调整,如

int backtrack(int (*p)[9]){
您可以像这样声明参数

int backtrack(int (*p)[9][9] ){
但在这种情况下,函数的调用类似

backtrack( puzzle );
backtrack( &puzzle );
而函数的主体将过于复杂。例如,访问原始数组元素的语法如下

p[i][j]
( *p )[i][j]
函数中也包含此语句

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

没有道理。不能以这种方式初始化数组。我认为这句话在函数的实现中是多余的。您已经拥有指向数组第一行的poinetr p。您可以使用此指针更改原始数组或遍历其元素。实际上,数组的所有元素都是通过指针p通过引用传递的。

使用赋值表达式不可能一次赋值给数组的所有元素,在定义数组时可以初始化数组的部分或所有元素

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

如果您这样声明回溯:

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]元素的任何修改都会修改原始数组

回溯中的参数arr的类型为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;     
}

不能使用初始化列表以外的值分配数组。只需像这样声明回溯:int backtrackint puzzle[9][9]这是复制列表还是仍然是原件,因为我需要修改原件,而不是副本。这将是原件。如果您将此作为答案,我将接受it@Pablo先走一步。