Passing pointer to 2D array c++

2019-03-28 11:05发布

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

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.

Thanks for help.

7条回答
狗以群分
2楼-- · 2019-03-28 11:13
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 );
} 
查看更多
冷血范
3楼-- · 2019-03-28 11:16

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

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

Making a typedef can simplify things:

typedef double d3x3[3][3];

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

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.

查看更多
【Aperson】
4楼-- · 2019-03-28 11:17

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.

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.

查看更多
不美不萌又怎样
5楼-- · 2019-03-28 11:25

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

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.

查看更多
霸刀☆藐视天下
6楼-- · 2019-03-28 11:28

In your main() function:

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.

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.

If you only want to return a pointer to an internal class member, you only really need a single pointer value in 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):

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楼-- · 2019-03-28 11:36

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?

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

...
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 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();
}
查看更多
登录 后发表回答