return C++ 中的二维数组

return 2D array in C++

我是 C++ 的新手,我在 python 中进行物理模拟,这需要很长时间才能完成,所以我决定切换到 C++,但我不明白如何制作一个函数将 return 一个 2D 数组(或 3D 数组)

#include <iostream>
#include <cmath>
// #include <complex> //

using namespace std;

double** psiinit(int L, int n, double alpha){
    double yj[400][400] = {};
    for (int j = 0; j < n; j++)
    {
        double xi[400] = {};
        for (int i = 0; i < n; i++)
        {
            xi[i] = exp(-(pow((i-(L/4)), 2) + (pow((j-(L/4)), 2)))/alpha) / (sqrt(2)*3.14159*alpha);
        };
        yj[j] = xi;
    };
    return yj;
}

int main(){
    int L = 10;
    int n = 400;
    int nt = 200*n;
    double alpha = 1;
    double m = 1;
    double hbar = 1;

    double x[n] = {};
    double y[n] = {};
    double t[nt] = {};

    double psi[nt][n][n] = {};
    psi[0] = psiinit(L, n, alpha);

    cout << psi <<endl;
    return 0;
}

我一直在寻找答案,但似乎不适合我的问题

谢谢

要么像上面说的那样制作一个包装器,要么使用一个向量的向量。

#include <vector>
#include <iostream>

auto get_2d_array()
{
    // use std::vector since it will allocate (the large amount of) data on the heap
    // construct a vector of 400 vectors with 400 doubles each
    std::vector<std::vector<double>> arr(400, std::vector<double>(400));
    arr[100][100] = 3.14;
    return arr;
}

int main()
{
    auto arr = get_2d_array();
    std::cout << arr[100][100];
}

如果您是 c++ 新手,您应该阅读堆和栈的概念以及栈帧。有很多好的资源。

简而言之,当您声明一个 C 风格数组(例如 yj)时,它是在函数的堆栈帧中创建的,因此一旦退出帧就无法保证它,并且您的程序在引用该 returned 数组时调用未定义的行为。

有3个选项:

  1. 将数组作为输出参数传递给函数(非常 C 风格,不推荐)。
  2. 将数组包装在 class 中(就像 std::array 已经为您做的一样),在这种情况下它保留在堆栈中并在 returned 时复制到调用帧, 但它的大小必须在编译时知道。
  3. 在堆上分配数组并 return 它,在我看来这最适合您的情况。 std::vector 为您做到这一点:
std::vector<std::vector<double>> psiinit(int L, int n, double alpha){
    std::vector<std::vector<double>> yj;
    for (int j = 0; j < n; j++)
    {
        std::vector<double> xi;
        for (int i = 0; i < n; i++)
        {
            const int value = exp(-(pow((i-(L/4)), 2) + (pow((j-(L/4)), 2)))/alpha) / (sqrt(2)*3.14159*alpha);
            xi.push_back(value);
        }

        yj.push_back(xi);
    }
    return yj;
}

如果您关心性能并且所有内部向量的大小都是固定的 N,那么使用 std::vector<std::array<double, N>>.

可能会更好

堆分配和返回指针也可以工作... 而不是

double yj[400][400] = {}; 

做,

double** yj; 
yj = new double*[400]; 
yj[i] = new double[400];

那么,

return yj;

您对数组、指针和 return 值的理解不完整。我无法就此主题为您编写完整的教程,但我建议您继续阅读。

同时,我建议您使用 std::vector 而不是 C 风格的数组,并将您的多维数组视为具有适当索引的一维向量,例如cell = vector[row * cols + col]

像这样:

#include <cmath>
// using std::exp, M_PI, M_SQRT2
#include <vector>

std::vector<double> psiinit(int L, int n, double alpha) {
    std::vector<double> yj(n * n);
    double div = M_SQRT2 * M_PI * alpha;
    for (int j = 0; j < n; j++)
    {
        double jval = j - L/4;
        jval = jval * jval;
        for (int i = 0; i < n; i++)
        {
            double ival = i - L/4;
            ival = ival * ival;
            yj[j * n + i] = std::exp(-(ival + jval) / alpha) / div;
        }
    }
    return yj;
}

附录:还有专门的库可以更好更快地支持矩阵。例如本征 https://eigen.tuxfamily.org/dox/GettingStarted.html