简体   繁体   English

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

[英]Passing pointer to 2D array c++

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. 我想将指针传递给外面的M矩阵。 It's probably very simple, but I just can't find the proper combination of & and * etc. 它可能很简单,但我找不到&*等的正确组合。

Thanks for help. 感谢帮助。

double *A[3][3]; is a 2-dimensional array of double * s. double * s的二维数组。 You want double (*A)[3][3]; 你想要double (*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,并且编译器确保您传递的是正确大小的数组。

Your intent is not clear. 你的意图不明确。 What is getpointeM supposed to do? getpointeM应该做什么? Return a pointer to the internal matrix (through the parameter), or return a copy of the matrix? 返回指向内部矩阵的指针(通过参数),还是返回矩阵的副本?

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();
}

The short answer is that you can get a double * to the start of the array: 简短的回答是你可以得到一个double *到数组的开头:

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. 你可以在主创建2D阵列,虽然(双A [3] [3]),并通过一个用GetPoint方法,该方法可以在值复制到传入的阵列。 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. 当然,缺点是您必须复制它。

In your main() function: 在你的main()函数中:

double *A[3][3];

creates a 3x3 array of double* (or pointers to doubles). 创建一个3x3的double*数组(或指向double*指针)。 In other words, 9 x 32-bit contiguous words of memory to store 9 memory pointers. 换句话说,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. 没有必要在main() 复制此数组,除非该类将被销毁,并且您仍然希望访问此信息。 Instead, you can simply return a pointer to the start of this member array. 相反,您只需返回指向此成员数组开头的指针即可。

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]);
}
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 );
} 

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. 您可能希望获取main函数中的代码,该函数使用2D双精度数组,并将其作为成员函数移动到myClass中。 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. 您不仅不必处理为该2D数组传递指针的困难,而且您的类外部的代码将不再需要知道您的类如何实现A的细节,因为它们现在将调用函数myClass并让它完成工作。 If, say, you later decided to allow variable dimensions of A and chose to replace the array with a vector of vector s, you wouldn't need to rewrite any calling code in order for it to work. 例如,如果你后来决定允许A的变量维并选择用vector s的vector替换数组,则不需要重写任何调用代码以使其工作。

Make M public instead of private. 使M公开而不是私人。 Since you want to allow access to M through a pointer, M is not encapsulated anyway. 由于您希望允许通过指针访问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]如果这是一个要求)和基准通常会导致更清晰的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM