我有很长一段时间遇到这个问题 - 我将固定大小的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
矩阵。它可能非常简单,但我找不到&
和*
等的正确组合。
感谢您的帮助。
答案 0 :(得分:9)
double *A[3][3];
是double *
s的二维数组。你想要double (*A)[3][3];
。
然后,请注意A
和*A
以及**A
都具有相同的地址,只是不同的类型。
制作typedef可以简化事情:
typedef double d3x3[3][3];
这是C ++,你应该通过引用传递变量,而不是指针:
void getpointeM( d3x3 &matrix );
现在您不需要在类型名称中使用parens,并且编译器会确保您传递的是正确大小的数组。
答案 1 :(得分: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();
}
答案 2 :(得分:0)
简短的回答是,您可以在数组的开头获得double *
:
public:
double * getMatrix() { return &M[0][0]; }
但是,在课堂之外,你不能真正轻易地将double *
直接转换为另一个2D数组,至少不是我用过的模式。
你可以在main中创建一个2D数组(双A [3] [3])并将传递给到一个getPoint方法,它可以将值复制到传入的数组中。这会给你一个副本,这可能是你想要的(而不是原始的,可修改的数据)。当然,缺点是你必须复制它。
答案 3 :(得分:0)
在main()
函数中:
double *A[3][3];
创建一个3x3的double*
数组(或指向双精度数的指针)。换句话说,存储9个内存指针的9 x 32位连续字。
除非该类将被销毁,您仍然需要访问此信息,因此无需在main()
中创建此数组的副本。相反,您只需返回指向此成员数组开头的指针。
如果您只想返回指向内部类成员的指针,那么main()
只需要一个指针值:
double *A;
但是,如果您将此指针传递给函数并且需要函数来更新其值,则需要一个双指针(这将允许函数返回 real 指针值致来电者:
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]);
}
答案 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)
您可能希望获取主函数中的代码,该函数与2D双精度数组一起使用,并将其作为成员函数移动到myClass中。您不仅不必处理为该2D数组传递指针的困难,而且您的类外部的代码将不再需要知道您的类如何实现A的细节,因为它们现在将调用函数myClass并让它完成工作。例如,如果你后来决定允许A的变量维并选择用vector
vector
替换数组,则不需要重写任何调用代码以使其工作
答案 6 :(得分: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 可能指向{ {1}}如果这是一项要求),参考通常会带来更清晰的代码。