c - 原地转置矩阵的函数

标签 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

最佳答案

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 变量。任何体面的编译器都会优化它们。

关于c - 原地转置矩阵的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46932439/

相关文章:

c - 父进程退出后如何让子进程终止?

c - 如何使用 malloc 获取 c 中指针的内存地址,然后在该地址分配 char 数组?

c - pthread : join a detached thread doesn't set errno correctly

javascript - 使用平均值、标准开发或回归来填充 Javascript 数组?

java - 如何验证二维数组/网格是否为 n^2*n^2

c - 字符串数组指针/数组名称的有效赋值是什么?

c++ - 在 C++ 中声明一个函数指针数组

c - 执行C程序时出现碎片错误

javascript - 随机显示问题的名称值对的多维数组(javascript/jquery)

澄清c中回调和函数指针的概念