C++ 如何引用二维指针?

C++ 如何引用二维指针?,c++,C++,在我的代码中,我在main之外创建了一个函数,它创建了一个1D数组并初始化为0 void create_grid(double *&y, int Npoints) { y = new double[Npoints]; for (int i = 0; i < Npoints; i++) { y[i] = 0; } } 所以你需要一个指向指针的指针引用 2d指针是int**,参考是int**&。这就是你想用的 然后,您应该使用一个容器,

在我的代码中,我在main之外创建了一个函数,它创建了一个1D数组并初始化为0

void create_grid(double *&y, int Npoints)
{
    y = new double[Npoints];
    for (int i = 0; i < Npoints; i++)
    {
        y[i] = 0;
    }
}

所以你需要一个指向指针的指针引用

2d指针是
int**
,参考是
int**&
。这就是你想用的


然后,您应该使用一个容器,或者至少是一个智能指针

解决/编写如此复杂的引用的一个简单技巧是(为了解决这个问题,简化了版本-使用大括号稍微复杂一些):从变量名开始,一步一步地向左走。就你而言:

<代码>y

y

<代码>&y

y
是一个参考

<代码>*&y

y
是对指针的引用

<代码>***&y

y
是对指向指针的指针的引用

double**&y

y
是对指向双精度指针的指针的引用

因此,正确的定义是:

void create_grid_2D(double**& y,int Npoints1,int Npoints2)

但如注释中所提到的,请确实考虑避免原始指针,而不是“代码> STD::vector < /Cuth>和其他标准容器。

C++不允许形成指向引用或引用的指针。(字符之间没有空格,

&&
是一个单独的标记,意思完全不同。)

以及您的声明
double z**不正确-您的意思可能是
double**z

要编写一个通过引用获取参数
double**z
的函数,只需引用指针到指针:

void create_grid_2D(double **&y,int Npoints1,int Npoints2)
{
    //...
}
除非不要使用
新建
删除
。稍有错误地使用它们会导致内存泄漏,并导致指针悬空和双重删除的错误。例如,您试图用
delete[]z清理
main
中的内存,但新表达式对一个删除表达式求值了11次,因此在删除行数组
z[0]
z[1]
<代码>z[9]
。使用
std::unique_ptr
std::shared_ptr
std::vector
,或其他RAII(资源分配是初始化)工具,总是有更好更简单的方法

因此,我将函数更改为:

void create_grid_2D(std::vector<std::vector<double>>& y,
                    unsigned int Npoints1,
                    unsigned int Npoints2)
{
    y.assign(Npoints1, std::vector<double>(Npoints2, 0.0));
}

int main()
{
    unsigned int N=10;
    std::vector<std::vector<double>> z;
    create_grid_2D(z, N, N);
    // No manual cleanup necessary.
}
void创建网格二维(std::vector&y,
无符号整数Npoints1,
无符号整数(Npoints2)
{
y、 赋值(Npoints1,std::vector(Npoints2,0.0));
}
int main()
{
无符号整数N=10;
std::向量z;
创建网格二维(z,N,N);
//无需手动清理。
}
或者甚至使用返回值而不是指定参数:

std::vector<std::vector<double>> create_grid_2D(
    unsigned int Npoints1,
    unsigned int Npoints2)
{
    return std::vector<std::vector<double>>(
        Npoints1, std::vector<double>(Npoints2, 0.0));
}

int main()
{
    unsigned int N=10;
    std::vector<std::vector<double>> z = create_grid_2D(N, N);
}
std::矢量创建网格\u 2D(
无符号整数Npoints1,
无符号整数(Npoints2)
{
返回std::vector(
Npoints1,std::vector(Npoints2,0.0));
}
int main()
{
无符号整数N=10;
std::vector z=创建网格2D(N,N);
}

此方法与您目前使用的方法略有不同,但基本上您需要一个2D网格,其另一个名称就是MxN矩阵!我们可以用一个简单的模板结构很容易地做到这一点。这个模板类将保存所有内容,而不必将数据直接放入动态内存。一旦你有了你想要使用的类对象,我们就可以使用智能指针把它放到动态内存中

#include <iostream>
#include <memory>

template<class T, unsigned M, unsigned N>
class Matrix {
    static const unsigned Row = M;
    static const unsigned Col = N;
    static const unsigned Size = Row * Col;
    T data[Size] = {};

public: 
    Matrix() {};
    Matrix( const T* dataIn ) {
        fillMatrix( dataIn );
    }

    void fillMatrix( const T* dataIn );
    void printMatrix() const;
};

template<class T, unsigned M, unsigned N>
void Matrix<T, M, N>::fillMatrix( const T* dataIn ) {
    for ( unsigned i = 0; i < Size; i++ ) {
        this->data[i] = dataIn[i];
    }
}

template<class T, unsigned M, unsigned N>
void Matrix<T,M,N>::printMatrix() {
    for ( unsigned i = 0; i < Row; i++ ) {
        for ( unsigned j = 0; j < Col; j++ ) {
            std::cout << this->data[i*Col + j] << " ";
        }
        std::cout << '\n';
    }
}

int main() {

    // our 1 day array of data
    double data[6] = { 1,2,3,4,5,6 };

    // create and print a MxN matrix - in memory still a 1 day array but represented as 2D array
    Matrix<double,2,3> A;
    A.fillMatrix( data );
    A.printMatrix();
    std::cout << '\n';

    Matrix<double, 3,2> B( data );
    B.printMatrix();
    std::cout << '\n';

    // Want this in dynamic memory? With shared_ptr the memory is handled for you
    // and is cleaned up upon it's destruction. This helps to eliminate memory leaks
    // and dangling pointers.
    std::shared_ptr<Matrix<float,2,3>> pMatrix( new Matrix<float,2,3>( data ) );

    pMatrix->printMatrix();

    return 0;
}

指针是
*y
,双指针,
**y
。添加引用运算符
&
令人困惑。。。实际上,看起来您正在取消指针尝试以下操作:
std::vector&y
不要使用原始指针和手动显式内存管理(
new
/
delete
)。使用标准容器,例如
std::vector
我想您应该使用原始数组和指针(为了练习)。如果要创建任意维度的二维数组,必须创建指向其他数组的指针数组(不是真正的二维数组,即使使用[i][j]访问它也是如此)。您可以制作一个模板,其中维度(例如NPoint)是编译时模板参数,而不是运行时函数参数。谢谢您,非常清楚地解释并回答了“问题”。如果我需要写C等价物并将函数符号更改为(double***y…),我是否需要每次使用它都遵从y(*y),或者我可以将遵从y分配给某个变量?@unlut根据需要,您可以使用变量前面的确切数量
*
s来“取消”变量类型中的
*
数量相同。@NunoTeixeira它们容易出错,可读性不强,也不太方便(正如您刚才所经历的那样)。容器更易于使用,更安全,在大多数情况下,它的效率与原始指针一样高。
#include <iostream>
#include <memory>

template<class T, unsigned M, unsigned N>
class Matrix {
    static const unsigned Row = M;
    static const unsigned Col = N;
    static const unsigned Size = Row * Col;
    T data[Size] = {};

public: 
    Matrix() {};
    Matrix( const T* dataIn ) {
        fillMatrix( dataIn );
    }

    void fillMatrix( const T* dataIn );
    void printMatrix() const;
};

template<class T, unsigned M, unsigned N>
void Matrix<T, M, N>::fillMatrix( const T* dataIn ) {
    for ( unsigned i = 0; i < Size; i++ ) {
        this->data[i] = dataIn[i];
    }
}

template<class T, unsigned M, unsigned N>
void Matrix<T,M,N>::printMatrix() {
    for ( unsigned i = 0; i < Row; i++ ) {
        for ( unsigned j = 0; j < Col; j++ ) {
            std::cout << this->data[i*Col + j] << " ";
        }
        std::cout << '\n';
    }
}

int main() {

    // our 1 day array of data
    double data[6] = { 1,2,3,4,5,6 };

    // create and print a MxN matrix - in memory still a 1 day array but represented as 2D array
    Matrix<double,2,3> A;
    A.fillMatrix( data );
    A.printMatrix();
    std::cout << '\n';

    Matrix<double, 3,2> B( data );
    B.printMatrix();
    std::cout << '\n';

    // Want this in dynamic memory? With shared_ptr the memory is handled for you
    // and is cleaned up upon it's destruction. This helps to eliminate memory leaks
    // and dangling pointers.
    std::shared_ptr<Matrix<float,2,3>> pMatrix( new Matrix<float,2,3>( data ) );

    pMatrix->printMatrix();

    return 0;
}
1 2 3
4 5 6

1 2 
3 4
5 6

1 2 3
4 5 6