简体   繁体   English

(在 C 中),如何转置矩阵?

[英](in C), how to transpose a matrix?

3rd EDIT: okay, I think I have figured it out how all this stuff can work.第三次编辑:好的,我想我已经弄清楚所有这些东西是如何工作的。 See at the bottom of the answer for my final explanation.我的最终解释见答案底部。

I have to do this exercise: given a matrix, write a function to transpose that matrix.我必须做这个练习:给定一个矩阵,写一个 function 来转置该矩阵。 It has to return a pointer to that matrix.它必须返回一个指向该矩阵的指针。

these are key points: (1) write a matrix constructor function这些是关键点:(1)编写矩阵构造函数function

(2) create the function with the help of the matrix constructor (2) 借助矩阵构造函数创建 function

(3) transpose the matrix (3) 转置矩阵

(4) print the matrix (4) 打印矩阵

(5) free the allocated memory (5)释放分配的memory

(6) close the file (6) 关闭文件

(for the moment, let's ignore step 4, step 5, and step 6) (暂时,让我们忽略第 4 步、第 5 步和第 6 步)

(1), and (2) the matrix constructor function is pretty simple, because it takes 3 parameters: "pointer to matrix", "rows", "columns". (1) 和 (2) 矩阵构造函数 function 非常简单,因为它需要 3 个参数:“指向矩阵的指针”、“行”、“列”。 Here's my code:这是我的代码:

void matrix_constructor(struct matrix* mat, size_t rows, size_t cols) {
    mat->rows = rows; mat->cols = cols; 
    mat->data = calloc(rows * cols, sizeof(double)); 
}

it works.有用。

(3) (this is the critical point). (3)(这是关键点)。 here's my code:这是我的代码:

struct matrix* mat_transpose(const struct matrix* mat) {
    struct matrix* out;

the error is located here.错误位于此处。 it's a warning (green squiggle): the debugger warned me I'm using uninitialized memory.这是一个警告(绿色曲线):调试器警告我我正在使用未初始化的 memory。 But I've initialized it in the next lines.但我已经在接下来的几行中对其进行了初始化。 Why do I have this warning?为什么我有这个警告? (this warning stops me from running the program; this is strange because a warning could be ignored, right?) (这个警告阻止我运行程序;这很奇怪,因为可以忽略警告,对吧?)

    out->rows = mat->cols; 
    out->cols = mat->rows; 
    out->data = mat->data; 
    for (size_t r = 0; r < out->rows; ++r) {
        for (size_t c = 0; c < out->cols; ++c) {
            out->data[r * out->cols + c] = mat->data[r * mat->rows + c]; 
        }
    }
    return out; 
}

..... ......

this is the reproducible example:这是可重现的例子:

matrix.h矩阵.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h> 
#include <stdio.h>
struct matrix {
    size_t rows, cols;
    double* data;
};
extern struct matrix* mat_transpose(const struct matrix* mat);

matrix.c矩阵.c

#include "matrix.h"

struct matrix* mat_transpose(const struct matrix* mat) {
    struct matrix* out; 
    out->rows = mat->cols; 
    out->cols = mat->rows; 
    out->data = mat->data; 
    for (size_t r = 0; r < out->rows; ++r) {
        for (size_t c = 0; c < out->cols; ++c) {
            out->data[r * out->cols + c] = mat->data[r * mat->rows + c]; 
        }
    }
    return out; 
} 

..... ......

to sum up:总结一下:

why do I have this warning?为什么我有这个警告? could you give me a detailed explanation about that?你能给我一个详细的解释吗?

EDIT: I've edited matrix_transpose function.编辑:我已经编辑了 matrix_transpose function。 and it works.它有效。 here's the code,这是代码,

struct matrix* mat_transpose(const struct matrix* mat) {
    struct matrix* out = calloc(mat->rows * mat->cols, sizeof(double));
    if (out == NULL) {
        return NULL; 
    }
    out->rows = mat->cols; 
    out->cols = mat->rows; 
    out->data = mat->data; 
    for (size_t r = 0; r < out->rows; ++r) {
        for (size_t c = 0; c < out->cols; ++c) {
            out->data[r * out->cols + c] = mat->data[r * mat->rows + c]; 
        }
    }
    return out; 
}

now, the mat_fprint function:现在,mat_fprint function:

void matrix_fprint(const struct matrix *m, FILE *f) {
    size_t rows = m->rows; 
    size_t cols = m->cols; 
    double* data = m->data; 

    for (size_t r = 0; r < rows; ++r) {
        for (size_t c = 0; c < cols; ++c) {
            double value = 0; 
            value = data[r * cols + c]; 
            fprintf(f, "%.4f", value); 
        }
    }
}

it doesn't have errors;它没有错误; but when I compile it, in the file I don't see anything (only one line of code, but it's not the entire matrix) I don't know why.但是当我编译它时,在文件中我什么都看不到(只有一行代码,但它不是整个矩阵)我不知道为什么。

EDIT 2: I've added \t and \n and I got the same result编辑 2:我添加了 \t 和 \n 并且得到了相同的结果

void matrix_fprint(const struct matrix *m, FILE *f) {
    size_t rows = m->rows; 
    size_t cols = m->cols; 
    double* data = m->data; 

    for (size_t r = 0; r < rows; ++r) {
        for (size_t c = 0; c < cols; ++c) {
            double value = 0; 
            value = data[r * cols + c]; 
            fprintf(f, "%.4f\t", value); 
        }
        fprintf(f, "\n"); 
        
    }
    
}

the output on file is the same.文件上的 output 是一样的。

3rd EDIT: this is the, hopefully, final reproducible example.第三次编辑:希望这是最终的可重现示例。

// matrix.h 

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h> 
#include <stdio.h>
struct matrix {
    size_t rows, cols;
    double* data;
};
extern struct matrix* mat_transpose(const struct matrix* mat);

// matrix.c


#include "matrix.h"

void matrix_constructor(struct matrix* mat, size_t rows, size_t cols) {
    mat->rows = rows; mat->cols = cols;
    mat->data = calloc(rows * cols, sizeof(double));
}

struct matrix* mat_transpose(const struct matrix* mat) {
    // allocate the matrix structure
    struct matrix* out = calloc(sizeof(*out), 1);
    if (out == NULL) {
        return NULL;
    }
    // construct the transposed matrix with rows and cols arguments swapped
    matrix_constructor(out, mat->cols, mat->rows);
    if (out->data == NULL) {
        free(out);
        return NULL;
    }
    // set the transposed data
    for (size_t r = 0; r < mat->rows; ++r) {
        for (size_t c = 0; c < mat->cols; ++c) {
            out->data[c * out->rows + r] = mat->data[r * mat->rows + c];
        }
    }
    return out;
}

void matrix_fprint(const struct matrix *m, FILE *f) {
    size_t rows = m->rows; 
    size_t cols = m->cols; 
    double* data = m->data; 

    for (size_t r = 0; r < rows; ++r) {
        for (size_t c = 0; c < cols; ++c) {
            double value = 0; 
            value = data[r * cols + c]; 
            fprintf(f, "%.4f\t", value); 
        }
        fprintf(f, "\n"); 
        
    }
    
}



void matrix_destructor(struct matrix* mat) {
    free(mat->data); 
}



int main(void) {
    struct matrix A; 
    matrix_constructor(&A, 2, 3); 
    A.data[0] = 4.5678; A.data[1] = 78.9876; A.data[2] = 67.9876; 
    A.data[3] = 4.7896; A.data[4] = 2.6789; A.data[5] = 1.1122;
    
    mat_transpose(&A); 
    FILE* f = fopen("matrix transpose.txt", "w"); 
    matrix_fprint(&A, f); 

    matrix_destructor(&A); 
    fclose(f); 
    return 0; 
} 

the problem is that when I compile the code, I read in the file the original matrix (matrix A), and not the transpose matrix.问题是当我编译代码时,我在文件中读取了原始矩阵(矩阵 A),而不是转置矩阵。

hypothesis: this could happen because when matrix_transpose return the value, it's not assigned to any struct variable.假设:这可能会发生,因为当 matrix_transpose 返回值时,它没有分配给任何结构变量。

But when I try to create, for example, "struct matrix B" it doesn't work as well.但是,当我尝试创建例如“结构矩阵 B”时,它就不能正常工作了。 why?为什么?

struct matrix* out; 

This does not initialize a matrix, it initializes a pointer to a matrix.这不会初始化矩阵,它会初始化指向矩阵的指针。 Since the pointer hasn't been initialized, it currently points to some arbitrary address in memory.由于指针尚未初始化,它目前指向 memory 中的某个任意地址。 (Which is probably memory that you don't own!) (这可能是您不拥有的 memory!)

That is why the compiler is giving you a warning;这就是编译器向您发出警告的原因; you are (probably) editing memory that you don't own!您(可能)正在编辑您不拥有的 memory!

If you want to allocate space for a matrix, you can use malloc from #include <stdlib.h> .如果要为矩阵分配空间,可以使用#include <stdlib.h>中的malloc

You need to allocate both the matrix structure and the matrix data.您需要同时分配matrix结构和矩阵数据。 You can use matrix_constructor for that:您可以为此使用matrix_constructor

struct matrix *mat_transpose(const struct matrix *mat) {
    // allocate the matrix structure
    struct matrix *out = calloc(sizeof(*out), 1);
    if (out == NULL) {
        return NULL; 
    }
    // construct the transposed matrix with rows and cols arguments swapped
    matrix_constructor(out, mat->cols, mat->rows);
    if (out->data == NULL) {
        free(out);
        return NULL;
    }
    // set the transposed data
    for (size_t r = 0; r < mat->rows; ++r) {
        for (size_t c = 0; c < mat->cols; ++c) {
            out->data[c * out->rows + r] = mat->data[r * mat->rows + c]; 
        }
    }
    return out; 
}
  1. create the function with the help of the matrix constructor在矩阵构造函数的帮助下创建function

You probably mean "create the MATRIX with help of the matrix constructor FUNCTION".您可能的意思是“在矩阵构造函数 FUNCTION 的帮助下创建矩阵”。


given a matrix, write a function to transpose that matrix .给定一个矩阵,写一个 function 来转置该矩阵 It has to return a pointer to that matrix .它必须返回指向该矩阵的指针。

This is badly formulated and unclear.这是错误的表述和不清楚。 Is there a second matrix or not?是否有第二个矩阵?

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

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