Как создать матричную структуру в C? - PullRequest
0 голосов
/ 01 июля 2018

Я новичок в C, но в настоящее время я пытаюсь создать матричную структуру данных, которая могла бы использоваться в различных функциях без необходимости явно передавать число столбцов и количество строк (пример: matrixMult(matrix A, matrix B) вместо matrixMult(A, B, rowsA, columnsA, rowsB, columnsB)). Мой подход до сих пор состоял в том, чтобы объявить такую ​​структуру, как

typedef struct matrix{
    int rows;
    int columns;
    int **data;
}matrix;

А затем, чтобы правильно выделить матрицу, я пытаюсь использовать следующую функцию

matrix startmatrix(matrix mat,int n_row, int n_col){
    int i=0;
    mat.rows=n_row;
    mat.columns=n_col;

    mat.data=(int **) calloc(n_row,sizeof(int *));

    for(i=0;i<n_row;i++){
        mat.data[i]=(int *) calloc(n_col,sizeof(int));
    }
    return mat;
}

Который (насколько я понимаю) выделяет строки, содержащие столбцы, а затем выделяет память для столбцов, которые затем содержат фактические данные.

Приведенная выше часть кода , кажется, работает нормально, однако, когда я пытаюсь ввести некоторые данные в матрицу, а затем визуализировать их позже, например ::

A=startmatrix(A,2,3);
A.data[1,1]=1;
printf("%d",A.data[1,1]);

Возвращает предупреждение (присваивание делает указатель из целого числа без приведения) и число 4 внутри фактической матрицы.

Может кто-нибудь объяснить, что я делаю не так?


РЕДАКТИРОВАТЬ: Добавление полного кода, который я использую. Пока что он состоит из двух файлов: mainfile.c и matrix.h. Теперь я также понимаю (спасибо!), Что передача mat в startmatrix бесполезна и что я должен использовать A.data[][], поэтому я соответственно отредактировал код. На данный момент основной файл:

//Mainfile.c
#include <stdio.h>
#include <stdlib.h>
#include "matrix.h"


int main(){
    matrix A=startmatrix(2,3); //2 by 3 matrix
    A.data[1][1]=1; /*testing to see if the value 1 is passed to the first cell*/

    printf("\n%d\n",A.rows); //Prints number of rows stored by A
    printf("\n%d\n",A.columns); //Prints number of cols stored by A
    printf("\n%d\n\n",A.data[1][1]);  //Is supposed to print the value stored in the first cell
    return 0;
}

Это вызывает файл "matrix.h", который содержит следующее (и пока только следующее)

#include <stdlib.h>

typedef struct matrix{
    int rows, columns;
    int **data;
}matrix;

matrix startmatrix(int n_row, int n_col){
    matrix mat;
    int i=0;
    mat.rows=n_row;
    mat.columns=n_col;

    mat.data=(int **) calloc(n_row,sizeof(int *));

    for(i=0;i<n_row;i++){
        mat.data[i]=(int *) calloc(n_col,sizeof(int));
    }
    return mat;
}

Пока это весь код, который я использовал для этой проблемы, ничего более или менее. Я читаю предложенные ответы и комментарии и пробую их, чтобы увидеть, работают ли они. Заранее спасибо за помощь.

Ответы [ 2 ]

0 голосов
/ 01 июля 2018

Как начинающий программист C, вы должны узнать и, по крайней мере, изначально избегать сложных случаев арифметики указателей. В случае матрицы вы можете сделать все просто. Я позволил себе добавить базовое обнаружение ошибок, используя assert.

Для начала используйте один указатель, когда это возможно:

typedef struct matrix{
    int rows;
    int columns;
    int *data;
}matrix;

Адаптируйте процедуру распределения:

matrix startmatrix(int n_row, int n_col){
    assert(n_row>0 && n_col>0);
    matrix mat;
    mat.rows=n_row;
    mat.columns=n_col;
    mat.data=calloc(n_row*n_col,sizeof(int)); /* allocate memory and clear to zero */
    return mat; /* return copy of mat */
}

Прототип этих функций показался мне немного забавным, поэтому я немного его изменил. Он должен иметь тот же эффект, что и старый.

Если вы хотите максимально использовать структуру, используйте функции доступа вместо работы с необработанным индексом массива:

int* matrixcell(matrix mat, int column, int row){
    assert(column < mat.columns && row < mat.rows);
    return &mat.data[row*mat.columns + column]; /* pointer arithmetic */
}
/* example of using it */
*matrixcell(mat, 1, 1) = new_value;

Арифметика - очень простой способ навигации по 2D-данным в одномерном массиве. Попробуйте это на ручке и бумаге, написание делает адреса каждой ячейки. Вы увидите, что это имеет смысл.

0 голосов
/ 01 июля 2018

Вы не можете получить доступ к такому двухмерному массиву - C не рассматривает его как таковой, для компилятора это просто указатель на указатель на целое число. C также не распознает систему множественного индексирования (несколько индексов, разделенных запятыми).

Вы должны получить доступ к строке с помощью A.data[1], которая дает вам указатель на конкретную строку, а затем получить доступ к нужному элементу в ней - A.data[1][1].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...