指向2D数组作为c函数中的参数的指针
我正在写一个数独解题程序,我对使用2D数组的指针有点困惑。目前,我正在定义这样一个谜题: 然后我有一个叫做backtrack的函数,它将使用backtrack递归地解决这个问题。我需要将谜题传递到回溯,以便在函数内部修改它。当前回溯看起来像指向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
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先走一步。