我在C
中编写了以下函数double * transpose(double *M, int n) {
double *T = (double *) malloc(n * n * sizeof(double));
int i, j;
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
T[i + (j * n)] = M[(i * n) + j];
}
}
return T;
}
我称之为:
C = transpose(C, n);
其中C
之前已声明为
double *C = (double *) malloc(n * n * sizeof(double));
然后用值初始化。
我怎样才能,而不是返回T
,将我的函数类型设置为void,然后调用等效的*M = *T
而不是return
语句。换句话说,我该如何调用函数:
transpose(C, n);
以便*C
指向由*T
创建的内存分配?
编辑:
正如下面的wildplasser所指出的,将矩阵转置到位的更有效方法是交换{i,j}对,除了沿对角线。
有些事情如下:
void * transpose(double *M, int n) {
int i, j;
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
if (i != j) {
double temp = M[i + (j * n)];
M[i + (j * n)] = M[(i * n) + j];
M[(i * n) + j] = temp;
}
}
}
}
但是,将其称为
transpose(C, n);
不允许C
在函数后保留它的转置。我在这里做错了什么?
GCC也给了我警告
Utilities.c: In function 'transpose':
Utilities.c:34:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
我在头文件和源文件中都将我的函数定义为void
?
答案 0 :(得分:0)
首先,您的代码存在内存泄漏。您可以覆盖C
之前的值,而不会释放它。
要进行转置,您只需交换所有正确的索引而无需交换两次。所以它就像反转阵列一样存在问题。
void transpose(double *M, int n) {
int i, j;
double temp;
for(i = 0; i < n; i++) {
for(j = 0; j < i; j++) {
temp = M[i + j * n];
M[i + j * n] = M[j + i * n];
M[j + i * n] = temp;
}
}
}
答案 1 :(得分:0)
void transpose(double *arr, size_t siz)
{
size_t ii,jj;
for(ii=0;ii<siz;ii++) {
for(jj=ii+1;jj<siz;jj++){
double tmp;
size_t aa,bb;
aa = ii+ siz * jj;
bb = jj+ siz * ii;
tmp = arr[aa];
arr[aa] = arr[bb];
arr[bb] = tmp;
}
}
}
不要担心aa
和bb
变量。任何体面的编译器都会优化它们。
答案 2 :(得分:-1)
void transpose(double **C, double *M, int n) {
double *T = (double *) malloc(n * n * sizeof(double));
int i, j;
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
T[i + (j * n)] = M[(i * n) + j];
}
}
*C = T;
}
并按照以下方式调用您的函数:
transpose(&C, n);
由于评论建议先释放旧C以避免内存泄漏