简体   繁体   English

在C中使用指针转置矩阵

[英]Transpose Matrix Using Pointer in C

I was doing the assignment to use pointer to transpose matrices. 我正在做分配以使用指针转置矩阵。 My code can successfully transpose the first row of the matrix but fail to transpose other rows and columns. 我的代码可以成功转置矩阵的第一行,但无法转置其他行和列。 I suspect there's some problems with for loops but I cannot find where the problem is. 我怀疑for循环存在一些问题,但是我找不到问题所在。 The following attached is my code. 以下是我的代码。

void transposeMatrix(int matrix[ROWS][COLS]){
    int**  transpose=(int **)malloc(ROWS*sizeof(int*));
    for(int  i=0; i< ROWS; i++)
        transpose[i]=(int*)malloc(COLS*sizeof(int));

    for(int  i=0; i<ROWS;i++){
        puts("");
        for(int  j=0; j<COLS;j++){
            *(transpose+i*ROWS+j)= *(matrix+j*COLS+i);
            printf("%d ",transpose[j][i]);
        }
        puts("");
    }
}

The matrix generates random numbers and the problems looks like this: 矩阵生成随机数,问题看起来像这样:

Original Matrix:
10 20 30
40 50 60
70 80 90

Transpose Matrix:
10 0 43009213
20 3401401 910429
30 0 134910124

I cannot attach the image so the above is just an elaboration of the problem I faced, the real situation is not exactly like that but very similar. 我无法附上图片,因此上述内容只是我所遇到问题的详细说明,实际情况并非完全一样,而是非常相似。

Thank you for your help! 谢谢您的帮助!

*(transpose+i*ROWS+j) is not the correct way to access elements of an array of pointers. *(transpose+i*ROWS+j)不是访问指针数组元素的正确方法。 That's the way to access a 2-dimensional array that's stored contiguously in row-major order in an int[] array or through an int* pointer. 这就是访问二维数组的方式,该二维数组按行优先顺序连续存储在int[]数组中或通过int*指针存储。

The way to access an element of a 2-dimensional array that's implemented as an array of pointers is with *(*(transpose + i)+j) . 访问以指针数组形式实现的二维数组元素的方法是使用*(*(transpose + i)+j) *(transpose + i) returns the pointer to row i , adding j to that returns the address of the j 'th column in the row, and deferencing that gets or sets the value. *(transpose + i)返回指向第i行的指针,向其添加j返回该行中第j列的地址,并进行递延以获取或设置该值。

This will also work with an array declared as 这也适用于声明为

int matrix[ROWS][COLS];

because of the way arrays decay to pointers. 因为数组衰减到指针的方式。

So your assignment line should be: 因此,您的任务行应为:

        *(*(transpose + i)+j) = *(*(matrix + j)+i);

Then you need to change the printf() line, because it's not printing the same element you just assigned. 然后,您需要更改printf()行,因为它不会打印您刚刚分配的相同元素。 It should be: 它应该是:

        printf("%d ", transpose[i][j]);

The full working function is: 完整的工作功能是:

void transposeMatrix(int matrix[ROWS][COLS]){
    int**  transpose=(int **)malloc(ROWS*sizeof(int*));
    for(int  i=0; i< ROWS; i++)
        transpose[i]=(int*)malloc(COLS*sizeof(int));

    for(int  i=0; i<ROWS;i++){
        puts("");
        for(int  j=0; j<COLS;j++){
            *(*(transpose + i)+j) = *(*(matrix + j)+i);
            printf("%d ",transpose[i][j]);
        }
        puts("");
    }
}

You have problem with identifying memory location for row and col of each cells Here is the way using them: 您在确定每个单元格的行和列的内存位置时遇到问题,这是使用它们的方式:

i-th rows of transpose = *(transpose + i)
j-th col in i-th row of transpose  = *(*(transpose+i) + j)

Similar to matrix: 类似于矩阵:

i-th rows of matrix= *(matrix + i)
j-th col in i-th row of matrix  = *(*(matrix+i) + j)

So here is my solution: 所以这是我的解决方案:

void transposeMatrix(int matrix[ROWS][COLS]) {
    int**  transpose = (int **)malloc(ROWS * sizeof(int*));
    for (int i = 0; i < ROWS; i++)
        transpose[i] = (int*)malloc(COLS * sizeof(int));

    for (int i = 0; i < ROWS; i++) {
        puts("");
        for (int j = 0; j < COLS; j++) {
            *(*(transpose + i) + j) = *(*(matrix + j) + i);
            printf("%d ", transpose[i][j]);
        }
        puts("");
    }
}

It's not necessary for you to allocate a new matrix row by row. 您不必逐行分配新的矩阵。 Also, the functions that do the transpose and printing can be passed straight int * rather than preshaped arrays like int [3][2] etc. 另外,进行转置和打印的函数可以直接传递给int *而不是像int [3][2]等预成形数组。

It's even possible to reshape the matrix in place (ie without allocating new space). 甚至有可能在适当的位置重塑矩阵(即无需分配新空间)。 If you like I can post example code for that later. 如果您愿意,我可以稍后发布示例代码。

For instance: 例如:

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

int M[2][3] = { {1, 2, 3}, {7, 8, 9} };
int N[3][3] = { {1, 2, 3}, { 4, 5, 6 }, {7, 8, 9} };


int *alloc_transpose(const int *matrix, size_t rows, size_t cols);
void print_matrix(const int *matrix, size_t rows, size_t cols);

int main()
{
    int *t_matrix;
    print_matrix(&M[0][0], 2, 3);
fprintf(stderr, "----\n");
    t_matrix = alloc_transpose(&M[0][0], 2, 3);
    if (t_matrix) {
        print_matrix(t_matrix, 3, 2);
    }
    free(t_matrix);
    t_matrix = alloc_transpose(&N[0][0], 3, 3);
    if (t_matrix) {
    fprintf(stderr, "----\n");
        print_matrix(t_matrix, 3, 3);
    }
    free(t_matrix);
    return 0;
}

void print_matrix(const int *matrix, size_t rows, size_t cols)
{
    size_t r, c;
    for (r = 0; r < rows; r++) {
        for (c = 0; c < cols; c++) {
            printf("%d ", *((matrix + r * cols) + c));
        }
        putchar('\n');
    }
}

int *alloc_transpose(const int *matrix, size_t rows, size_t cols)
{
    int *tm;
    int r, c;       /* relative to transposed matrix */

    tm = malloc(sizeof(int) * cols * rows); /* contiguous is okay */

    if (!tm)
        return NULL;

    for (r = 0; r < rows; r++) {
        for (c = 0; c < cols; c++) {
            *((tm + c * rows) + r) =
                          *((matrix + r * cols) + c);
        }
    }

    return tm;
}

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

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