6

我有这个问题很长一段时间 - 我已经固定大小的 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(); ???

} 

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

感谢帮助。

4

7 回答 7

9

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

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

制作 typedef 可以简化事情:

typedef double d3x3[3][3];

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

void getpointeM( d3x3 &matrix );

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

于 2010-02-22T04:46:26.410 回答
3

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

要返回一个指针,你可以这样做

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

对于retpointM声明将如下所示

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

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

typedef double M3x3[3][3];

在这种情况下,上述示例将转换为

// 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();
}
于 2010-02-22T05:24:26.833 回答
0

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

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

但是,在课堂之外,您不能真正将double *直接转换为另一个二维数组,至少不能以我见过的模式使用。

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

于 2010-02-22T04:43:08.317 回答
0

在您的main()功能中:

double *A[3][3];

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

除非该类将被销毁,否则无需在其中制作此数组的副本main(),并且您仍想访问此信息。相反,您可以简单地返回一个指向此成员数组开头的指针。

如果你只想返回一个指向内部类成员的指针,你只需要一个指针值main()

double *A;

但是,如果你将这个指针传递给一个函数并且你需要函数更新它的值,你需要一个双指针(这将允许函数将真正的指针值返回给调用者:

double **A;

在内部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]);
}
于 2010-02-22T04:46:59.763 回答
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 );
} 
于 2010-02-22T04:51:54.343 回答
0

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

于 2010-02-22T05:45:28.327 回答
0

使 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;
}

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

于 2010-02-22T07:41:56.120 回答