我有这个C ++类Matrix(请参见下面的代码片段)。
在我的随机方法中,我设置了matr的所有值(matr是2x2矩阵)。
当我调用print_matrix时,它正在复制元素(1,0)和(1,1)并将它们都打印两次,以及不打印(0,0)或(0,1)。
我做错了什么?
请参见下面的输出。
class Matrix {
public:
int rows;
int cols;
double rnd;
double* matr;
Matrix(int a, int b) {
printf(" vals %d %d \n", a, b);
rows = a;
cols = b;
matr = new double[a, b];
//this->print_matrix();
//clear_matrix();
//this->print_matrix();
//this->randomize();
//this->print_matrix();
}
double &at(int pos1, int pos2) {
return matr[pos1, pos2];
};
void setPos(int pos1, int pos2, double value) {
matr[pos1, pos2] = value;
};
void randomize() {
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
rnd = double(rand()) / double((RAND_MAX)+1.0);
printf("Rand : %d, C: %d, Val: %f \n",r,c, rnd);
this->setPos(r, c, rnd);
//matr[r, c] = rnd;
printf("New value R: %d C: %d Val: %f \n", r, c, matr[r,c]);
//rnd = 0;
}
}
};
void subtract_Scalar(double val) {
double curr_Val = 0;
double result = 0;
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
curr_Val = this->at(r, c);
result = curr_Val - val;
this->setPos(r, c, 0);
this->setPos(r, c, (float)result);
//this->setPos(r, c, 5);
//printf("SS CV : %f, Re: %f \n", curr_Val, result);
curr_Val = 0;
result = 0;
}
}
};
void print_matrix() {
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
printf("PM R : %d, C: %d Val: %f \n", r, c, matr[r,c]);
//printf("%f", this->at(r, c));
}
//printf("\n");
}
}
void clear_matrix() {
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
this->setPos(r, c, 0.0);
}
}
}
};
最佳答案
由于以下行,您的程序具有未定义的行为:
printf("PM R : %d, C: %d Val: %f \n", r, c, matr[r,c]);
matr[r,c]
不访问矩阵的元素。由于使用了逗号运算符,因此它只是matr[c]
,其结果为一个指针。您正在使用%f
打印指针。那是未定义的行为部分。您需要使用matr[r][c]
访问矩阵的元素。printf("PM R : %d, C: %d Val: %f \n", r, c, matr[r][c]);
matr[r, c]
的使用不正确。有关更多详细信息,请参见the documentation of the comma operator。
更新资料
由于@PeteBecker敏锐的眼睛,这个问题与我最初的想法不同。
事实证明,
matr
是double*
类型。因此,matr[c]
计算结果为双精度。因此,该程序没有未定义的行为。不管c
的值如何,它始终一直访问matr
-r
的元素。问题开始于:
matr = new double[a, b];
它必须是
matr = new double[a * b];
使用
matr[r, c]
访问矩阵元素的任何位置,都必须为matr[r*cols + c]
。在
at
中,您需要使用:return matr[pos1 * cols + pos2];
在
setPos
中,您需要使用:matr[pos1 * cols + pos2] = value;
在
randomize
中,您需要使用:printf("New value R: %d C: %d Val: %f \n", r, c, matr[r*cols + c]);
在
print_matrix
中,您需要使用:printf("PM R : %d, C: %d Val: %f \n", r, c, matr[r*cols + c]);
通过为
at
非const
对象提供const
的重载,可以简化用于访问元素的代码。double& at(int r, int c) { return matr[r*cols + c]; }
double at(int r, int c) const { return matr[r*cols + c]; }
然后,
setPos
可以实现为: void setPos(int pos1, int pos2, double value) {
at(pos1, pos2) = value;
};
printf
行可以更新为:printf("New value R: %d C: %d Val: %f \n", r, c, at(r, c));
printf("PM R : %d, C: %d Val: %f \n", r, c, at(r, c));