仍然需要掌握C中的指针,所以如果这有一个简单的解释我不会感到惊讶......
我有代码在C中执行矩阵乘法。为此,我定义了一个自定义矩阵结构,它对行主要1D数组中的整个矩阵进行编码,以避免传递双指针:
typedef struct matrix matrix;
struct matrix {
int n_rows;
int n_cols;
double *entries;
};
问题是当我将指向此矩阵结构的指针作为arg传递给我的矩阵乘法函数时。
matrix *matrix_mult(matrix *m, matrix *n){
if (m->n_cols != n->n_rows){
fprintf(stderr, "dimension mismatch\n");
exit(1);
} else {
int rows = m->n_rows;
int cols = n->n_cols;
matrix *new = (matrix*)malloc(8+rows*cols*sizeof(double));
new->n_rows = rows;
new->n_cols = cols;
new->entries = (double*)malloc(rows*cols*sizeof(double));
for (int i = 0; i < rows*cols; i++) new->entries[i] = dot_prod( row_vec(m, i/cols), col_vec(n, i%cols) );
}
return new;
}
这样写,当整个矩阵传递给matrix_mult时,某些矩阵元素会被神秘地清零!例如,我有一个3x3矩阵* M,其条目初始化为:
1.000000 0.000000 0.000000 0.250000 1.000000 0.000000 0.062500 0.500000 1.000000
当我将* M传递给matrix_mult并询问matrix_mult printf时,我发现它们是现在的条目(这是在矩阵mult执行之前):
1.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.062500 0.500000 0.000000
但是,当我按如下方式修改matrix_mult时,明确定义行和列向量以执行点积:
matrix *matrix_mult(matrix *m, matrix *n){
/* code */
for (i = 0; i < rows*cols; i++){
rv = row_vec(m, i/cols);
cv = col_vec(n, i%cols);
new->entries[i] = dot_prod( rv, cv );
matrix_free(rv);
matrix_free(cv);
}
return new;
}
使用matrix_mult printf,M的条目现在给出:
1.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.062500 0.500000 1.000000
因此,改变(看似无关的)代码以某种方式修改了矩阵条目的值!有什么线索?
编辑: dot_prod函数如下:
/* takes the dot product of a row vector with a column vector;
returns error if args are not row or column vectors;
or if the size of the vectors are not equal */
double dot_prod(matrix *rv, matrix *cv){
if ((rv->n_rows != 1) || (cv->n_cols != 1)){
fprintf(stderr, "arg(s) are not row or column vectors\n");
exit(1);
} else if (rv->n_cols != cv->n_rows){
fprintf(stderr, "dimension mismatch\n");
exit(2);
} else {
double n = 0;
int l = rv->n_cols;
for (int i = 0; i < l; i++) n += rv->entries[i]*cv->entries[i];
return n;
}
}
答案 0 :(得分:0)