用于将矩阵转置到位的功能

时间:2017-10-25 12:27:17

标签: c arrays pointers

我在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

3 个答案:

答案 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;
                }
        }
}

不要担心aabb变量。任何体面的编译器都会优化它们。

答案 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以避免内存泄漏