将指针传递给2D数组c ++

时间:2021-02-27 21:37:37

I'm having this problem for quite a long time - I have fixed sized 2D array as a class member.

我有很长一段时间遇到这个问题 - 我将固定大小的2D数组作为类成员。

class myClass
{ 
public:
        void getpointeM(...??????...);
        double * retpointM();

private:

   double M[3][3];

};

int main()
{
     myClass moo;
     double *A[3][3];

     moo.getpointM( A );  ???
     A = moo.retpointM(); ???

} 

I'd like to pass pointer to M matrix outside. It's probably very simple, but I just can't find the proper combination of & and * etc.

我想将指针传递给外面的M矩阵。它可能很简单,但我找不到&和*等的正确组合。

Thanks for help.

感谢帮助。

7 个解决方案

#1


9  

double *A[3][3]; is a 2-dimensional array of double *s. You want double (*A)[3][3]; .

double * A [3] [3];是double * s的二维数组。你想要双(* A)[3] [3]; 。

Then, note that A and *A and **A all have the same address, just different types.

然后,请注意A和* A和** A都具有相同的地址,只是不同的类型。

Making a typedef can simplify things:

制作typedef可以简化事情:

typedef double d3x3[3][3];

This being C++, you should pass the variable by reference, not pointer:

这是C ++,你应该通过引用传递变量,而不是指针:

void getpointeM( d3x3 &matrix );

Now you don't need to use parens in type names, and the compiler makes sure you're passing an array of the correct size.

现在您不需要在类型名称中使用parens,并且编译器确保您传递的是正确大小的数组。

#2


3  

Your intent is not clear. What is getpointeM supposed to do? Return a pointer to the internal matrix (through the parameter), or return a copy of the matrix?

你的意图不明确。什么是getpointeM应该做的?返回指向内部矩阵的指针(通过参数),还是返回矩阵的副本?

To return a pointer, you can do this

要返回指针,您可以执行此操作

// Pointer-based version
...
void getpointeM(double (**p)[3][3]) { *p = &M; }
...
int main() {
  double (*A)[3][3];
  moo.getpointM(&A);
}

// Reference-based version
...
void getpointeM(double (*&p)[3][3]) { p = &M; }
...
int main() {
  double (*A)[3][3];
  moo.getpointM(A);
}

For retpointM the declaration would look as follows

对于retpointM,声明如下所示

...
double (*retpointM())[3][3] { return &M; }
...
int main() {
  double (*A)[3][3];
  A = moo.retpointM();
}

This is rather difficult to read though. You can make it look a lot clearer if you use a typedef-name for your array type

但这很难阅读。如果对数组类型使用typedef-name,则可以使其看起来更清晰

typedef double M3x3[3][3];

In that case the above examples will transform into

在这种情况下,上述例子将转变为

// Pointer-based version
...
void getpointeM(M3x3 **p) { *p = &M; }
...
int main() {
  M3x3 *A;
  moo.getpointM(&A);
}

// Reference-based version
...
void getpointeM(M3x3 *&p) { p = &M; }
...
int main() {
  double (*A)[3][3];
  moo.getpointM(A);
}

// retpointM
...
M3x3 *retpointM() { return &M; }
...
int main() {
  M3x3 *A;
  A = moo.retpointM();
}

#3


0  

The short answer is that you can get a double * to the start of the array:

简短的回答是你可以得到一个双* *到数组的开头:

public:
   double * getMatrix() { return &M[0][0]; }

Outside the class, though, you can't really trivially turn the double * into another 2D array directly, at least not in a pattern that I've seen used.

但是,在课堂之外,你不能真正轻易地将double *转换成另一个2D数组,至少不是我用过的模式。

You could create a 2D array in main, though (double A[3][3]) and pass that in to a getPoint method, which could copy the values into the passed-in array. That would give you a copy, which might be what you want (instead of the original, modifiable, data). Downside is that you have to copy it, of course.

您可以在main中创建一个2D数组(双A [3] [3])并将其传递给getPoint方法,该方法可以将值复制到传入的数组中。那会给你一个副本,这可能是你想要的(而不是原始的,可修改的数据)。当然,缺点是您必须复制它。

#4


0  

class myClass
{ 
public:
        void getpointeM(double *A[3][3])
        {
           //Initialize array here
        }

private:

   double M[3][3];

};

int main()
{
     myClass moo;
     double *A[3][3];

     moo.getpointM( A );
} 

#5


0  

You may want to take the code in your main function which works with the 2D array of doubles, and move that into myClass as a member function. Not only would you not have to deal with the difficulty of passing a pointer for that 2D array, but code external to your class would no longer need to know the details of how your class implements A, since they would now be calling a function in myClass and letting that do the work. If, say, you later decided to allow variable dimensions of A and chose to replace the array with a vector of vectors, you wouldn't need to rewrite any calling code in order for it to work.

您可能希望获取main函数中的代码,该函数使用2D数组的双精度数,并将其作为成员函数移动到myClass中。您不仅不必处理为该2D数组传递指针的难度,而且您的类外部的代码将不再需要知道您的类如何实现A的细节,因为它们现在将调用函数myClass并让它完成工作。例如,如果你后来决定允许A的变量维并选择用向量向量替换数组,则不需要重写任何调用代码以使其工作。

#6


0  

In your main() function:

在你的main()函数中:

double *A[3][3];

creates a 3x3 array of double* (or pointers to doubles). In other words, 9 x 32-bit contiguous words of memory to store 9 memory pointers.

创建一个3x3的double *数组(或指向double的指针)。换句话说,9 x 32位连续的内存字存储9个内存指针。

There's no need to make a copy of this array in main() unless the class is going to be destroyed, and you still want to access this information. Instead, you can simply return a pointer to the start of this member array.

没有必要在main()中复制此数组,除非该类将被销毁,并且您仍然希望访问此信息。相反,您只需返回指向此成员数组开头的指针即可。

If you only want to return a pointer to an internal class member, you only really need a single pointer value in main():

如果您只想返回指向内部类成员的指针,那么在main()中只需要一个指针值:

double *A;

But, if you're passing this pointer to a function and you need the function to update its value, you need a double pointer (which will allow the function to return the real pointer value back to the caller:

但是,如果您将此指针传递给函数并且需要函数来更新其值,则需要一个双指针(这将允许函数将实际指针值返回给调用者:

double **A;

And inside getpointM() you can simply point A to the internal member (M):

在getpointM()里面你可以简单地将A指向内部成员(M):

getpointeM(double** A)
{
    // Updated types to make the assignment compatible
    // This code will make the return argument (A) point to the
    // memory location (&) of the start of the 2-dimensional array
    // (M[0][0]).
    *A = &(M[0][0]);
}

#7


0  

Make M public instead of private. Since you want to allow access to M through a pointer, M is not encapsulated anyway.

让M公开而不是私人。由于您希望允许通过指针访问M,因此无论如何都不会封装M.

struct myClass { 
  myClass() {
    std::fill_n(&M[0][0], sizeof M / sizeof M[0][0], 0.0);
  }
  double M[3][3];
};

int main() {
  myClass moo;
  double (*A)[3] = moo.M;
  double (&R)[3][3] = moo.M;

  for (int r = 0; r != 3; ++r) {
    for (int c = 0; c != 3; ++c) {
      cout << A[r][c] << R[r][c] << ' ';
      // notice A[r][c] and R[r][c] are the exact same object
      // I'm using both to show you can use A and R identically
    }
  }

  return 0;
}

I would, in general, prefer R over A because the all of the lengths are fixed (A could potentially point to a double[10][3] if that was a requirement) and the reference will usually lead to clearer code.

一般来说,我会优先选择R而不是A,因为所有的长度都是固定的(如果需要的话,A可能指向double [10] [3])并且引用通常会导致更清晰的代码。

#1


9  

double *A[3][3]; is a 2-dimensional array of double *s. You want double (*A)[3][3]; .

double * A [3] [3];是double * s的二维数组。你想要双(* A)[3] [3]; 。

Then, note that A and *A and **A all have the same address, just different types.

然后,请注意A和* A和** A都具有相同的地址,只是不同的类型。

Making a typedef can simplify things:

制作typedef可以简化事情:

typedef double d3x3[3][3];

This being C++, you should pass the variable by reference, not pointer:

这是C ++,你应该通过引用传递变量,而不是指针:

void getpointeM( d3x3 &matrix );

Now you don't need to use parens in type names, and the compiler makes sure you're passing an array of the correct size.

现在您不需要在类型名称中使用parens,并且编译器确保您传递的是正确大小的数组。

#2


3  

Your intent is not clear. What is getpointeM supposed to do? Return a pointer to the internal matrix (through the parameter), or return a copy of the matrix?

你的意图不明确。什么是getpointeM应该做的?返回指向内部矩阵的指针(通过参数),还是返回矩阵的副本?

To return a pointer, you can do this

要返回指针,您可以执行此操作

// Pointer-based version
...
void getpointeM(double (**p)[3][3]) { *p = &M; }
...
int main() {
  double (*A)[3][3];
  moo.getpointM(&A);
}

// Reference-based version
...
void getpointeM(double (*&p)[3][3]) { p = &M; }
...
int main() {
  double (*A)[3][3];
  moo.getpointM(A);
}

For retpointM the declaration would look as follows

对于retpointM,声明如下所示

...
double (*retpointM())[3][3] { return &M; }
...
int main() {
  double (*A)[3][3];
  A = moo.retpointM();
}

This is rather difficult to read though. You can make it look a lot clearer if you use a typedef-name for your array type

但这很难阅读。如果对数组类型使用typedef-name,则可以使其看起来更清晰

typedef double M3x3[3][3];

In that case the above examples will transform into

在这种情况下,上述例子将转变为

// Pointer-based version
...
void getpointeM(M3x3 **p) { *p = &M; }
...
int main() {
  M3x3 *A;
  moo.getpointM(&A);
}

// Reference-based version
...
void getpointeM(M3x3 *&p) { p = &M; }
...
int main() {
  double (*A)[3][3];
  moo.getpointM(A);
}

// retpointM
...
M3x3 *retpointM() { return &M; }
...
int main() {
  M3x3 *A;
  A = moo.retpointM();
}

#3


0  

The short answer is that you can get a double * to the start of the array:

简短的回答是你可以得到一个双* *到数组的开头:

public:
   double * getMatrix() { return &M[0][0]; }

Outside the class, though, you can't really trivially turn the double * into another 2D array directly, at least not in a pattern that I've seen used.

但是,在课堂之外,你不能真正轻易地将double *转换成另一个2D数组,至少不是我用过的模式。

You could create a 2D array in main, though (double A[3][3]) and pass that in to a getPoint method, which could copy the values into the passed-in array. That would give you a copy, which might be what you want (instead of the original, modifiable, data). Downside is that you have to copy it, of course.

您可以在main中创建一个2D数组(双A [3] [3])并将其传递给getPoint方法,该方法可以将值复制到传入的数组中。那会给你一个副本,这可能是你想要的(而不是原始的,可修改的数据)。当然,缺点是您必须复制它。

#4


0  

class myClass
{ 
public:
        void getpointeM(double *A[3][3])
        {
           //Initialize array here
        }

private:

   double M[3][3];

};

int main()
{
     myClass moo;
     double *A[3][3];

     moo.getpointM( A );
} 

#5


0  

You may want to take the code in your main function which works with the 2D array of doubles, and move that into myClass as a member function. Not only would you not have to deal with the difficulty of passing a pointer for that 2D array, but code external to your class would no longer need to know the details of how your class implements A, since they would now be calling a function in myClass and letting that do the work. If, say, you later decided to allow variable dimensions of A and chose to replace the array with a vector of vectors, you wouldn't need to rewrite any calling code in order for it to work.

您可能希望获取main函数中的代码,该函数使用2D数组的双精度数,并将其作为成员函数移动到myClass中。您不仅不必处理为该2D数组传递指针的难度,而且您的类外部的代码将不再需要知道您的类如何实现A的细节,因为它们现在将调用函数myClass并让它完成工作。例如,如果你后来决定允许A的变量维并选择用向量向量替换数组,则不需要重写任何调用代码以使其工作。

#6


0  

In your main() function:

在你的main()函数中:

double *A[3][3];

creates a 3x3 array of double* (or pointers to doubles). In other words, 9 x 32-bit contiguous words of memory to store 9 memory pointers.

创建一个3x3的double *数组(或指向double的指针)。换句话说,9 x 32位连续的内存字存储9个内存指针。

There's no need to make a copy of this array in main() unless the class is going to be destroyed, and you still want to access this information. Instead, you can simply return a pointer to the start of this member array.

没有必要在main()中复制此数组,除非该类将被销毁,并且您仍然希望访问此信息。相反,您只需返回指向此成员数组开头的指针即可。

If you only want to return a pointer to an internal class member, you only really need a single pointer value in main():

如果您只想返回指向内部类成员的指针,那么在main()中只需要一个指针值:

double *A;

But, if you're passing this pointer to a function and you need the function to update its value, you need a double pointer (which will allow the function to return the real pointer value back to the caller:

但是,如果您将此指针传递给函数并且需要函数来更新其值,则需要一个双指针(这将允许函数将实际指针值返回给调用者:

double **A;

And inside getpointM() you can simply point A to the internal member (M):

在getpointM()里面你可以简单地将A指向内部成员(M):

getpointeM(double** A)
{
    // Updated types to make the assignment compatible
    // This code will make the return argument (A) point to the
    // memory location (&) of the start of the 2-dimensional array
    // (M[0][0]).
    *A = &(M[0][0]);
}

#7


0  

Make M public instead of private. Since you want to allow access to M through a pointer, M is not encapsulated anyway.

让M公开而不是私人。由于您希望允许通过指针访问M,因此无论如何都不会封装M.

struct myClass { 
  myClass() {
    std::fill_n(&M[0][0], sizeof M / sizeof M[0][0], 0.0);
  }
  double M[3][3];
};

int main() {
  myClass moo;
  double (*A)[3] = moo.M;
  double (&R)[3][3] = moo.M;

  for (int r = 0; r != 3; ++r) {
    for (int c = 0; c != 3; ++c) {
      cout << A[r][c] << R[r][c] << ' ';
      // notice A[r][c] and R[r][c] are the exact same object
      // I'm using both to show you can use A and R identically
    }
  }

  return 0;
}

I would, in general, prefer R over A because the all of the lengths are fixed (A could potentially point to a double[10][3] if that was a requirement) and the reference will usually lead to clearer code.

一般来说,我会优先选择R而不是A,因为所有的长度都是固定的(如果需要的话,A可能指向double [10] [3])并且引用通常会导致更清晰的代码。