简体   繁体   English

用C转置矩阵函数,函数接收和返回2D数组

[英]Transpose matrix function in C, with function receiving and returning a 2D array

I need to create a function that takes a matrix and returns it transpose. 我需要创建一个接受矩阵并返回转置的函数。 The only requirement is that it directly returns a matrix, not just modifies it by reference. 唯一的要求是它直接返回一个矩阵,而不仅仅是通过引用对其进行修改。 Here's what I've done so far: 到目前为止,这是我所做的:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define ROW 100000000
#define COL 100000000

int (*(f_MatTrans)(int mat[][COL], int r, int c))[COL];

int main(void)
{
int x[2][2]={1,2,3,4};
int (*a)[2];
a=f_MatTrans(x,2,2);

for(int i=0; i<2; i++)
{
    for(int j=0; j<2; j++)
    {
        printf("X[%d][%d]=%d\n",i,j,x[i][j]);
        printf("A[%d][%d]=%d\n",i,j,a[i][j]);
    }
}

return 0;
}

int (*(f_MatTrans)(int mat[][COL], int r, int c))[COL]
{
int a[c][r];

for(int i=0; i<r; i++)
{
    for(int j=0; j<c; j++)
    {
        a[j][i]=mat[i][j];
    }
}

return a;

}

The purpose of this is to include the function on a library created by myself, just in case it is useful information. 这样做的目的是在我自己创建的库中包含该函数,以防万一它是有用的信息。

You cannot return a pointer to the local array, because that ceases to exist when the function returns. 您不能返回指向本地数组的指针,因为函数返回时该指针将不再存在。 If you want your function to create the result array (not write to some other array that is passed into the function), you must use malloc() in these cases: 如果您希望函数创建结果数组(而不是写入传递给函数的其他数组),则在以下情况下必须使用malloc()

//The return type is actually `int (*)[r]`, but C doesn't like that.
int* f_MatTrans(int r, int c, int mat[][c]) {
    int (*a)[r] = malloc(c*sizeof(*a));
    for(int i=0; i<r; i++) {
        for(int j=0; j<c; j++) {
            a[j][i]=mat[i][j];
        }
    }
    return *a;
}

Note that I changed the array types: If you declare mat as int mat[][COL] , the number COL will be used to calculate the offset mat[1][0] , which will be 100000000 integers after the first element in your case, while the array that you pass in only contains four integers. 请注意,我更改了数组类型:如果将mat声明为int mat[][COL] ,则数字COL将用于计算偏移量mat[1][0] ,它将是您的第一个元素之后的100000000整数情况下,您传入的数组仅包含四个整数。 This is undefined behavior, and your program is allowed to format your harddrive if you do this. 这是未定义的行为,如果执行此操作,则允许程序格式化硬盘。

Unfortunately, it is not possible for the type of the returned pointer to depend on the value of an argument to the function. 不幸的是,返回的指针的类型不可能依赖于函数参数的值。 That is why I changed the return type to a plain integer pointer, you must document that this is meant to be a pointer of type int (*)[r] . 这就是为什么我将返回类型更改为普通整数指针的原因,您必须证明这意味着它是int (*)[r]类型的指针。

You would use the function above like this: 您将使用上面的函数,如下所示:

int main(void) {
    int x[2][3]={1,2,3,4,5,6};
    int (*a)[2] = (int (*)[2])f_MatTrans(2, 3, x);

    for(int i=0; i<2; i++) {
        for(int j=0; j<2; j++) {
            printf("X[%d][%d]=%d\n",i,j,x[i][j]);
            printf("A[%d][%d]=%d\n",i,j,a[i][j]);
        }
    }

    free(a);    //Cleanup!
    return 0;
}

The code in the question (when I read it) doesn't compile because the array x is not compatible with the function signature. 由于数组x与函数签名不兼容,因此问题(当我阅读时)中的代码无法编译。

I'm not clear what the real constraints on your problem are. 我不清楚您的问题的真正约束是什么。 The easy way to do it in C99 or C11 is with VLA notation: 在C99或C11中执行此操作的简单方法是使用VLA表示法:

#include <stdio.h>

static void MatrixTranspose(int r, int c, int src[r][c], int dst[c][r])
{
    for (int i = 0; i < r; i++)
        for (int j = 0; j < c; j++)
            dst[j][i] = src[i][j];
}

int main(void)
{
    int x[3][2] = { { 0, 1 }, { 2, 3 }, { 4, 5 } };
    int y[2][3];

    MatrixTranspose(3, 2, x, y);

    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 2; j++)
        {
            printf("X[%d][%d]=%d  ", i, j, x[i][j]);
            printf("Y[%d][%d]=%d\n", j, i, y[j][i]);
        }
    }

    return 0;
}

Sample output: 样本输出:

X[0][0]=0  Y[0][0]=0
X[0][1]=1  Y[1][0]=1
X[1][0]=2  Y[0][1]=2
X[1][1]=3  Y[1][1]=3
X[2][0]=4  Y[0][2]=4
X[2][1]=5  Y[1][2]=5

My suspicion is that you are supposed to be doing something different (notationally more complex), but it is not yet clear what. 我的怀疑是您应该做一些不同的事情(从概念上讲更复杂),但目前尚不清楚。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM