C语言函数参数为二维数组指针的疑问——数独求解场景
数独回溯函数中二维数组的指针传参解决方案
嗨,我来帮你搞定这个二维数组指针传参的问题——这在数独递归求解里确实是个容易懵的点,咱们一步步理清楚:
一、正确的函数参数写法
在C语言里,当你要把int puzzle[9][9]这样的二维数组传给函数时,有两种等价的参数写法,都能正确识别数组的结构:
写法1:直接使用二维数组形式
这种写法最直观,和你定义数组的方式一致,编译器会自动把它转换为指向一维数组的指针:
bool backtrack(int puzzle[9][9], int row, int col) { // 在这里可以直接用puzzle[row][col]访问元素 // 你的回溯逻辑写在这里 }
写法2:显式使用指向一维数组的指针
如果你想明确体现指针的本质,可以写成这样,和上面的写法完全等价:
bool backtrack(int (*puzzle)[9], int row, int col) { // 同样可以用puzzle[row][col]访问元素 // 回溯逻辑... }
这里的int (*puzzle)[9]表示puzzle是一个指向包含9个int元素的一维数组的指针,刚好匹配你9x9数独数组的结构。
二、调用函数时的传参方式
调用回溯函数的时候,直接把数组名puzzle传进去就行——因为数组名本身就代表数组首元素的地址,这里的首元素是第一个长度为9的一维数组,正好对应上面的指针类型:
int main() { 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, 0, 0); // 从第0行第0列开始回溯 return 0; }
三、避坑提醒:别用int **puzzle
很多初学者会误以为二维数组可以用int **来接收,但这是错误的!因为int puzzle[9][9]是一块连续的内存,而int **是指向指针的指针,两者的内存布局完全不同,用它接收二维数组会导致访问内存出错,一定要避开这个坑。
四、函数内的元素访问
不管用哪种参数写法,在函数里访问数独元素的方式和你原来直接操作数组的方式完全一样,比如要获取第row行第col列的元素,直接写puzzle[row][col]就可以,编译器会自动帮你处理指针的偏移计算。
举个简单的回溯逻辑片段示例:
bool backtrack(int (*puzzle)[9], int row, int col) { // 找到下一个空白格(值为0的位置) while (row < 9 && puzzle[row][col] != 0) { col++; if (col == 9) { row++; col = 0; } } // 所有格子都填满,返回true表示求解成功 if (row == 9) return true; // 尝试填入1-9的数字 for (int num = 1; num <= 9; num++) { if (isValid(puzzle, row, col, num)) { // 假设你有一个合法性检查函数 puzzle[row][col] = num; if (backtrack(puzzle, row, col)) { // 递归填充 return true; } puzzle[row][col] = 0; // 回溯,撤销选择 } } return false; // 所有数字都尝试过,无解 }
内容的提问来源于stack exchange,提问作者dangee1705
相关产品推荐
相关产品推荐

