C++ 如何引用二维指针?
在我的代码中,我在main之外创建了一个函数,它创建了一个1D数组并初始化为0C++ 如何引用二维指针?,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**&。这就是你想用的 然后,您应该使用一个容器,
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