#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    cin>>n;
    // write your code here......
    int *p=new int[n*n];
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            p[i+j]=i+j;
            cout<<p[i+j]<<" ";
        }
        cout<<endl;
    }
    return 0;
}


你遇到的报错核心原因是:int (*p)[n] 中的 n 是通过 cin 输入的运行时变量,但C++要求这个指针类型里的数组维度必须是编译期常量(编译时就能确定的值),因此编译器判定 n 不合法并报错。我会先解释错误本质,再给你3种可行的修正方案(按新手友好度排序)。

错误原因详细解析

int (*p)[n] 是“指向包含 n 个int的一维数组的指针”,这种指针类型的定义规则是:

  • 方括号里的 n 必须是常量表达式(比如 const int n=3#define N 3,编译时就能确定值);
  • 你代码中的 n 是运行时通过 cin 输入的(程序运行后才知道值),编译器无法在编译期确定 n 的大小,因此报错;
  • 补充:new int[n][n] 本身是合法的(new 的维度支持运行时变量),但左边的指针类型 int (*p)[n] 不支持运行时 n,这是矛盾的核心。

解决方案(按推荐优先级排序)

方案1:现代C++首选 — vector<vector<int>>(新手友好,无内存坑)

无需关注指针/常量表达式,自动管理内存,是最推荐的写法:

#include<bits/stdc++.h>
using namespace std;

int main(){
    int n;
    cin>>n;
    
    // 核心修改:用vector创建动态二维数组,支持运行时n
    vector<vector<int>> p(n, vector<int>(n)); // n行n列,默认初始化为0
    
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            p[i][j] = i + j;
            cout<<p[i][j]<<" ";
        }
        cout<<endl;
    }
    
    // 无需手动释放内存,vector自动处理
    return 0;
}

方案2:一维数组模拟二维数组(内存连续,性能最优)

这是之前讲过的写法,完全避开常量表达式问题,且内存连续、访问更快:

#include<bits/stdc++.h>
using namespace std;

int main(){
    int n;
    cin>>n;
    
    // 核心修改:动态一维数组模拟二维数组
    int* p = new int[n*n]; // 分配n×n个int的连续内存
    
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            p[i*n + j] = i + j; // 关键:i*n + j 换算二维下标
            cout<<p[i*n + j]<<" ";
        }
        cout<<endl;
    }
    
    // 必须释放内存(仅需一次delete[])
    delete[] p;
    p = nullptr;
    return 0;
}

方案3:改用int** 动态二维数组(兼容旧写法,内存非连续)

如果坚持用指针实现“看起来像二维数组”的写法,可改用 int**,但内存非连续:

#include<bits/stdc++.h>
using namespace std;

int main(){
    int n;
    cin>>n;
    
    // 核心修改:先分配行指针,再分配每行的列
    int** p = new int*[n]; // 分配n个行指针
    for(int i=0; i<n; i++){
        p[i] = new int[n]; // 为每行分配n列
    }
    
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            p[i][j] = i + j;
            cout<<p[i][j]<<" ";
        }
        cout<<endl;
    }
    
    // 必须手动释放内存(先释每行,再释行指针)
    for(int i=0; i<n; i++){
        delete[] p[i];
    }
    delete[] p;
    p = nullptr;
    return 0;
}

三种方案对比(新手快速选择)

vector<vector<int>>

新手友好、自动释放内存、语法直观

内存非连续(性能略低)

日常开发(首选)

一维数组模拟

内存连续、性能最高、内存管理简单

需手动换算下标

性能敏感场景(矩阵/算法)

int** 动态二维数组

语法接近原生二维数组

内存非连续、需循环释放

兼容旧C++代码

总结

  1. 报错根源是 int (*p)[n] 中的 n 必须是编译期常量,而你用了运行时输入的 n
  2. 新手优先选 vector<vector<int>>,无需关注内存管理和下标换算;
  3. 若追求性能,选一维数组模拟二维数组int* p = new int[n*n] + 下标 i*n+j);
  4. 避免再用 int (*p)[n] 处理运行时动态大小的二维数组,这是C++语法规则不允许的。