You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

传递多维数组时出错,求原因及解决方法(附N皇后回溯代码)

多维数组传递错误的成因与解决办法

兄弟,我一眼就看穿你代码里的问题了——就是二维数组作为函数参数传递时踩的C++语法坑!咱们先把问题掰碎了说:

错误成因

C对多维数组的类型要求很严格:当你把二维数组传给函数时,除了第一维可以留空,其他所有维度必须是编译期就能确定的常量。你代码里的s是函数参数,属于运行时才会确定的值,编译器在编译阶段根本不知道s到底是多少,自然没法计算数组元素在内存里的偏移地址(毕竟二维数组在内存里是连续存储的,得靠固定的第二维大小来定位元素)。所以int arr[][s]这种写法直接违反了C的语法规则,编译器肯定会报错。

解决办法

给你几个实用的方案,按需选择:

方案1:用编译期常量定义数组大小

如果你的N皇后问题里的棋盘大小是固定的(比如8皇后),直接把s改成编译期常量就行:

#include <iostream>
using namespace std;

// 用constexpr或者#define定义常量
constexpr int s = 8;

bool attack_checking(int arr[][s], int i, int j) {
    // 检查行
    for(int x = 0; x < s; x++)
        if(arr[i][x] == 1) return true;
    // 检查列
    for(int x = 0; x < s; x++)
        if(arr[x][j] == 1) return true;
    // 检查对角线(补全你没写完的逻辑)
    for(int x = i, y = j; x >=0 && y >=0; x--, y--)
        if(arr[x][y] == 1) return true;
    for(int x = i, y = j; x < s && y < s; x++, y++)
        if(arr[x][y] == 1) return true;
    for(int x = i, y = j; x >=0 && y < s; x--, y++)
        if(arr[x][y] == 1) return true;
    for(int x = i, y = j; x < s && y >=0; x++, y--)
        if(arr[x][y] == 1) return true;
    return false;
}

int main() {
    int board[s][s] = {0};
    // 后续逻辑...
    return 0;
}

缺点:棋盘大小固定,没法动态调整。

方案2:改用std::vector<std::vector<int>>(最推荐)

C++的容器能完美解决动态数组的问题,而且不需要操心内存管理,代码更安全灵活:

#include <iostream>
#include <vector>
using namespace std;

bool attack_checking(const vector<vector<int>>& arr, int i, int j) {
    int s = arr.size();
    // 检查行
    for(int x = 0; x < s; x++)
        if(arr[i][x] == 1) return true;
    // 检查列
    for(int x = 0; x < s; x++)
        if(arr[x][j] == 1) return true;
    // 检查对角线
    for(int x = i, y = j; x >=0 && y >=0; x--, y--)
        if(arr[x][y] == 1) return true;
    for(int x = i, y = j; x < s && y < s; x++, y++)
        if(arr[x][y] == 1) return true;
    for(int x = i, y = j; x >=0 && y < s; x--, y++)
        if(arr[x][y] == 1) return true;
    for(int x = i, y = j; x < s && y >=0; x++, y--)
        if(arr[x][y] == 1) return true;
    return false;
}

int main() {
    int s = 8; // 这里可以动态输入s的值
    vector<vector<int>> board(s, vector<int>(s, 0));
    // 后续逻辑...
    return 0;
}

优点:支持动态调整棋盘大小,代码可读性高,还能避免数组越界的风险。

方案3:使用指针的指针(int**)

如果你坚持要用原生数组,可以用动态分配的指针数组,但要注意手动管理内存:

#include <iostream>
#include <cstdlib>
using namespace std;

bool attack_checking(int** arr, int s, int i, int j) {
    // 检查行
    for(int x = 0; x < s; x++)
        if(arr[i][x] == 1) return true;
    // 检查列
    for(int x = 0; x < s; x++)
        if(arr[x][j] == 1) return true;
    // 检查对角线
    for(int x = i, y = j; x >=0 && y >=0; x--, y--)
        if(arr[x][y] == 1) return true;
    for(int x = i, y = j; x < s && y < s; x++, y++)
        if(arr[x][y] == 1) return true;
    for(int x = i, y = j; x >=0 && y < s; x--, y++)
        if(arr[x][y] == 1) return true;
    for(int x = i, y = j; x < s && y >=0; x++, y--)
        if(arr[x][y] == 1) return true;
    return false;
}

int main() {
    int s = 8;
    // 动态分配指针数组
    int** board = (int**)malloc(s * sizeof(int*));
    for(int i = 0; i < s; i++) {
        board[i] = (int*)malloc(s * sizeof(int));
        // 初始化数组为0
        for(int j = 0; j < s; j++)
            board[i][j] = 0;
    }

    // 后续逻辑...

    // 记得释放内存
    for(int i = 0; i < s; i++)
        free(board[i]);
    free(board);
    return 0;
}

缺点:需要手动分配和释放内存,容易出现内存泄漏或野指针问题,不推荐新手使用。

方案4:模板函数(适配编译期常量大小)

如果你想保留原生数组的性能,同时支持不同的固定大小,可以用模板函数:

#include <iostream>
using namespace std;

template<int s>
bool attack_checking(int arr[][s], int i, int j) {
    // 检查行
    for(int x = 0; x < s; x++)
        if(arr[i][x] == 1) return true;
    // 检查列
    for(int x = 0; x < s; x++)
        if(arr[x][j] == 1) return true;
    // 检查对角线
    for(int x = i, y = j; x >=0 && y >=0; x--, y--)
        if(arr[x][y] == 1) return true;
    for(int x = i, y = j; x < s && y < s; x++, y++)
        if(arr[x][y] == 1) return true;
    for(int x = i, y = j; x >=0 && y < s; x--, y++)
        if(arr[x][y] == 1) return true;
    for(int x = i, y = j; x < s && y >=0; x++, y--)
        if(arr[x][y] == 1) return true;
    return false;
}

int main() {
    const int s = 8;
    int board[s][s] = {0};
    // 调用时编译器会自动推导模板参数s
    bool isAttacked = attack_checking(board, 2, 3);
    // 后续逻辑...
    return 0;
}

优点:保留原生数组的性能,支持不同的固定大小;缺点:还是没法动态调整大小,s必须是编译期常量。

内容的提问来源于stack exchange,提问作者Vivek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:29:32