简体   繁体   English

C动态二维矩阵结构挫折

[英]C dynamic 2d Matrices struct frustration

I searched all over the internet and watched tons of video and nobody does this thing : Create a struct matrix that can dynamicly change its KxN direct from the main , for example I will use java :我在互联网上搜索并观看了大量视频,但没有人这样做:创建一个结构矩阵,可以直接从主动态更改其 KxN,例如我将使用 java:

Matrix(int k , int n){
int Mat[k][n];
}
main(){
Matrix a = new Matrix (2,3);
a.Mat[0][0] = 1;
syso(a.Mat[0][0]);
}

Im begining to think its imposible , I tried to alocate memory from the main and it worked , this is how I did it我开始认为这是不可能的,我尝试从主要分配内存并且它起作用了,这就是我做到的

int** arr = malloc(sizeof(int*)*n)
for (int i = 0 ; i < k ; i=+){
arr[i] = malloc(sizeof(int)*3);
}

but the problem is I cannot do it inside a struct for some reason .. I need to keep my main clean so all my work should be done above the main ,但问题是由于某种原因,我无法在结构内执行此操作。

this is my C program that doesn't work :这是我的 C 程序不起作用:

//__________________HEADER_________________________________________________//

#include <stdio.h>
#include <stdlib.h>
//__________________________________________________________________________//
//__________________OBJECTS______________________________________________________//

typedef struct { 
int n , k ;
int** Mat;
}Matrix;
//______________________________________________________________________________//

//___________________MAIN_____________________________________________________//

int main (void) {
printf("Start..\n\n");


Matrix aqq = {2,5} ;

aqq.Mat[0][0] = 5 ;

printf("\n  size : %dx%d    first element : %d \n",aqq.n , aqq.k , aqq.Mat[0][0]);


printf("\n\nEnd\n");
}
//______________________________________________________________________________//

I need to make all the getters and setter mult transpose all the matrices functions including linear copying guassian elemination .. everything and I would like to receive maybe a link to some guide lines or even a book , I don't care as long as I could study from it because its really difficult to work like that there are too many rules that involves memory and not a single reliable source of information because every body doing the easy stuff on the tutorials我需要让所有的 getter 和 setter 多转置所有的矩阵函数,包括线性复制高斯消除......一切,我想收到一些指南甚至一本书的链接,我不在乎,只要我可以从中学习,因为它真的很难像那样工作,涉及记忆的规则太多,而且没有一个可靠的信息来源,因为每个人都在教程中做简单的事情

so to sum up , the final goal is to control every function completely through the main综上所述,最终目标是通过主函数完全控制每个函数

Here's code that could be split into three files — matrix.h , matrix.c and test.matrix.c .下面的代码可以分成三个文件—— matrix.hmatrix.ctest.matrix.c

  1. The header matrix.h declares an opaque type Matrix and some functions to manipulate that type — a constructor (the third option in my comment ), a destructor, routines to get and set element values, and routines to get the array dimensions.头文件matrix.h声明了一个不透明类型Matrix和一些操作该类型的函数——一个构造函数(我的注释中的第三个选项)、一个析构函数、获取和设置元素值的例程以及获取数组维度的例程。

  2. The implementation file matrix.c defines the functions.实现文件matrix.c定义了函数。 It uses assertions to ensure the validity of arguments — lazy but effective as long as you never compile with -DNDEBUG .它使用断言来确保参数的有效性 - 只要您从不使用-DNDEBUG编译, -DNDEBUG懒惰但有效。 If you do suppress assertions, you need to put proper error handling into the functions.如果确实禁止断言,则需要在函数中进行适当的错误处理。 Deciding how to handle errors detected by corrupted data structures is a project-wide decision.决定如何处理由损坏的数据结构检测到的错误是一个项目范围的决定。 The code is careful to free any already allocated memory if there is an allocation failure during the construction of a matrix.如果在构造矩阵期间出现分配失败,代码会小心地释放任何已分配的内存。 It defines the struct Matrix , but that type is not accessible outside this source file.它定义了struct Matrix ,但在此源文件之外无法访问该类型。

  3. The test file test.matrix.c provides some code to use all the functions declared in matrix.h and demonstrates that square and rectangular matrices work.测试文件test.matrix.c提供了一些代码来使用在matrix.h声明的所有函数,并演示了正方形和矩形矩阵的工作。 The code in this file cannot dereference the matrix structure;该文件中的代码不能取消对矩阵结构的引用; it must use the access functions.它必须使用访问功能。

The resulting code is quite big, but it does the job and demonstrates that you can indeed use structures to store matrices.生成的代码相当大,但它可以完成工作并证明您确实可以使用结构来存储矩阵。 Write a matrix multiplication routine is a simple exercise.编写矩阵乘法例程是一个简单的练习。

/* SOF - matrix.h */
#ifndef MATRIX_H_INCLUDED
#define MATRIX_H_INCLUDED

#include <stddef.h>     /* size_t */

enum { MATRIX_MAX_SIZE = 1000 };

typedef struct Matrix Matrix;   /* Opaque type */

extern Matrix *matrix_constructor(size_t rows, size_t cols);
extern void matrix_destructor(Matrix *mtx);
extern int matrix_get_element(const Matrix *mtx, size_t r, size_t c);
extern void matrix_set_element(Matrix *mtx, size_t r, size_t c, int v);
extern size_t matrix_get_cols(const Matrix *mtx);
extern size_t matrix_get_rows(const Matrix *mtx);

#endif /* MATRIX_H_INCLUDED */
/* EOF - matrix.h */

/* SOF - matrix.c */
/*#include "matrix.h"*/
#include <assert.h>
#include <stdlib.h>

struct Matrix
{
    size_t   rows;
    size_t   cols;
    int    **data;
};

/* It is important to prevent memory leaks on allocation failure */
Matrix *matrix_constructor(size_t rows, size_t cols)
{
    assert(rows <= MATRIX_MAX_SIZE && rows > 0);
    assert(cols <= MATRIX_MAX_SIZE && cols > 0);
    Matrix *mtx = malloc(sizeof(*mtx));
    if (mtx == NULL)
        return NULL;
    mtx->data = malloc(sizeof(*mtx->data) * rows);
    if (mtx->data == NULL)
    {
        free(mtx);
        return NULL;
    }
    for (size_t i = 0; i < rows; i++)
    {
        mtx->data[i] = malloc(sizeof(*mtx->data[i]) * cols);
        if (mtx->data[i] == NULL)
        {
            while (i > 0)
                free(mtx->data[--i]);
            free(mtx);
            return NULL;
        }
    }
    mtx->rows = rows;
    mtx->cols = cols;
    return mtx;
}

void matrix_destructor(Matrix *mtx)
{
    assert(mtx != NULL && mtx->data != NULL);
    assert(mtx->rows <= MATRIX_MAX_SIZE && mtx->rows > 0);
    assert(mtx->cols <= MATRIX_MAX_SIZE && mtx->cols > 0);
    for (size_t i = 0; i < mtx->rows; i++)
        free(mtx->data[i]);
    free(mtx->data);
    free(mtx);
}

int matrix_get_element(const Matrix *mtx, size_t r, size_t c)
{
    assert(mtx != NULL && mtx->data != NULL);
    assert(mtx->rows <= MATRIX_MAX_SIZE && mtx->rows > 0);
    assert(mtx->cols <= MATRIX_MAX_SIZE && mtx->cols > 0);
    return mtx->data[r][c];
}

void matrix_set_element(Matrix *mtx, size_t r, size_t c, int v)
{
    assert(mtx != NULL && mtx->data != NULL);
    assert(mtx->rows <= MATRIX_MAX_SIZE && mtx->rows > 0);
    assert(mtx->cols <= MATRIX_MAX_SIZE && mtx->cols > 0);
    mtx->data[r][c] = v;
}

size_t matrix_get_rows(const Matrix *mtx)
{
    assert(mtx != NULL && mtx->data != NULL);
    assert(mtx->rows <= MATRIX_MAX_SIZE && mtx->rows > 0);
    assert(mtx->cols <= MATRIX_MAX_SIZE && mtx->cols > 0);
    return mtx->rows;
}

size_t matrix_get_cols(const Matrix *mtx)
{
    assert(mtx != NULL && mtx->data != NULL);
    assert(mtx->rows <= MATRIX_MAX_SIZE && mtx->rows > 0);
    assert(mtx->cols <= MATRIX_MAX_SIZE && mtx->cols > 0);
    return mtx->cols;
}
/* EOF - matrix.c */

/* SOF - test.matrix.c */
/*#include "matrix.h"*/
#include <errno.h>
#include <stdarg.h>
#include <stdint.h>     /* intmax_t */
#include <stdio.h>
/*#include <stdlib.h>*/
#include <string.h>
#include <time.h>

/* Cannot dereference Matrix pointers here! */

static void matrix_print(const char *tag, const Matrix *mtx, int width)
{
    size_t rows = matrix_get_rows(mtx);
    size_t cols = matrix_get_cols(mtx);
    printf("%s (%zux%zu):\n", tag, rows, cols);
    for (size_t r = 0; r < rows; r++)
    {
        const char *pad = "";
        for (size_t c = 0; c < cols; c++)
        {
            printf("%s%*d", pad, width, matrix_get_element(mtx, r, c));
            pad = ", ";
        }
        putchar('\n');
    }
}

static void matrix_random(Matrix *mtx)
{
    size_t rows = matrix_get_rows(mtx);
    size_t cols = matrix_get_cols(mtx);
    for (size_t r = 0; r < rows; r++)
    {
        for (size_t c = 0; c < cols; c++)
            matrix_set_element(mtx, r, c, (rand() % (rows * cols) + 1));
    }
}

static int i_log10(size_t n)
{
    if (n < 10)
        return 1;
    int c = 1;
    while (n >= 10)
    {
        n /= 10;
        c++;
    }
    return c;
}

static int i_pow10(int n)
{
    int r = 1;
    while (n-- > 0)
        r *= 10;
    return r;
}

static void matrix_ordered(Matrix *mtx)
{
    size_t rows = matrix_get_rows(mtx);
    size_t cols = matrix_get_cols(mtx);
    int mul = i_pow10(i_log10(cols));
    for (size_t r = 0; r < rows; r++)
    {
        for (size_t c = 0; c < cols; c++)
            matrix_set_element(mtx, r, c, (r + 1) * mul + c + 1);
    }
}

static void err_exit(const char *fmt, ...)
{
    va_list args;
    int errnum = errno;
    va_start(args, fmt);
    vfprintf(stderr, fmt, args);
    if (errnum != 0)
        fprintf(stderr, " (%d: %s)", errnum, strerror(errnum));
    putc('\n', stderr);
    exit(EXIT_FAILURE);
}

static Matrix *matrix_checked_constructor(const char *tag, size_t rows, size_t cols)
{
    Matrix *mp = matrix_constructor(rows, cols);
    if (mp == NULL)
        err_exit("Failed to construct matrix %s", tag);
    return mp;
}

int main(void)
{
    Matrix *mi5 = matrix_checked_constructor("MI5", 5, 5);
    Matrix *mi6 = matrix_checked_constructor("MI6", 6, 6);
    Matrix *ks69 = matrix_checked_constructor("KS69", 6, 9);
    Matrix *bw1815 = matrix_checked_constructor("BW1815", 18, 15);

    time_t now = time(0);
    srand(now);
    printf("Seed: %jd\n", (intmax_t)now);

    matrix_random(mi5);
    matrix_random(mi6);
    matrix_ordered(ks69);
    matrix_ordered(bw1815);

    matrix_print("MI5", mi5, 2);
    matrix_print("MI6", mi6, 2);
    matrix_print("KS69", ks69, 3);
    matrix_print("BW1815", bw1815, 4);

    matrix_destructor(mi5);
    matrix_destructor(mi6);

    return 0;
}
/* EOF - test.matrix.c */

Example output:示例输出:

Seed: 1605897737
MI5 (5x5):
14, 22,  5, 21, 11
23,  5, 23,  7,  2
10,  9,  9,  2, 24
10,  6, 21,  6, 11
 5, 11,  5, 18,  3
MI6 (6x6):
25, 33,  4, 18, 24, 19
 6,  1, 23, 19,  6, 24
17,  2, 26,  3,  2, 32
 7, 34,  8,  5, 11, 33
 6,  7, 34, 13, 21, 14
15, 25, 32, 11, 28, 28
KS69 (6x9):
 11,  12,  13,  14,  15,  16,  17,  18,  19
 21,  22,  23,  24,  25,  26,  27,  28,  29
 31,  32,  33,  34,  35,  36,  37,  38,  39
 41,  42,  43,  44,  45,  46,  47,  48,  49
 51,  52,  53,  54,  55,  56,  57,  58,  59
 61,  62,  63,  64,  65,  66,  67,  68,  69
BW1815 (18x15):
 101,  102,  103,  104,  105,  106,  107,  108,  109,  110,  111,  112,  113,  114,  115
 201,  202,  203,  204,  205,  206,  207,  208,  209,  210,  211,  212,  213,  214,  215
 301,  302,  303,  304,  305,  306,  307,  308,  309,  310,  311,  312,  313,  314,  315
 401,  402,  403,  404,  405,  406,  407,  408,  409,  410,  411,  412,  413,  414,  415
 501,  502,  503,  504,  505,  506,  507,  508,  509,  510,  511,  512,  513,  514,  515
 601,  602,  603,  604,  605,  606,  607,  608,  609,  610,  611,  612,  613,  614,  615
 701,  702,  703,  704,  705,  706,  707,  708,  709,  710,  711,  712,  713,  714,  715
 801,  802,  803,  804,  805,  806,  807,  808,  809,  810,  811,  812,  813,  814,  815
 901,  902,  903,  904,  905,  906,  907,  908,  909,  910,  911,  912,  913,  914,  915
1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015
1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115
1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215
1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1311, 1312, 1313, 1314, 1315
1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1415
1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 1515
1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615
1701, 1702, 1703, 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, 1714, 1715
1801, 1802, 1803, 1804, 1805, 1806, 1807, 1808, 1809, 1810, 1811, 1812, 1813, 1814, 1815

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

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