Этот ответ является полным излишеством, но это мой подход, основанный на struct
, который n.m. называется «целая «другая история».
Если это новая программа (т.е. вы можете определить, как выглядит ввод/вывод вашей функции) и вы собираетесь много работать с матрицами, я бы склонен использовать структуру для представления матрицы, и просто передавать указатели на экземпляры этой структуры.
В приведенном ниже коде показан один из возможных подходов. Обратите внимание, что здесь есть пара «трюков». Во-первых, все данные хранятся в одном непрерывном блоке — это может улучшить производительность по ряду причин. Одним из потенциальных недостатков этого метода является то, что изменение размера матрицы становится дорогостоящим, поскольку вам приходится выделять совершенно новый экземпляр и копировать данные. Но если вы обнаружите, что это проблема, вы всегда можете изменить свою реализацию, предполагая, что вы всегда используете функции matrix_get() и matrix_set() для доступа к значениям в матрице.
Кроме того, матричная структура и память, на которую указывает указатель данных, выделяются в одном вызове malloc. Если вы используете этот метод, просто помните о проблемах с выравниванием данных. Например, если вы измените данные, чтобы они указывали на 64-битные целые или двойные числа, вам нужно будет добавить заполнение, чтобы убедиться, что все выровнено по 8 байтам. В качестве альтернативы просто malloc
указатель данных как отдельный массив в функции new_matrix()
, при условии, что вы не забудете освободить его в free_matrix()
.
Я оставил в качестве упражнения для ОП, чтобы написать функцию умножения.
#include <stdio.h>
#include <stdlib.h>
struct matrix
{
int rows;
int cols;
int * data;
};
struct matrix * new_matrix( int rows, int cols )
{
struct matrix * m = NULL;
/* Allocate a block of memory large enough to hold the matrix 'header' struct
* as well as all the row/column data */
m = malloc( sizeof(struct matrix) + (rows * cols * sizeof(int) ) );
if( m )
{
m->rows = rows;
m->cols = cols;
/* Some ugly pointer math to get to the first byte of data */
m->data = (int*) ( (char *) m + sizeof(*m) );
}
return m;
}
void free_matrix( struct matrix * m )
{
free( m );
}
int matrix_set( struct matrix * m, int row, int col, int val)
{
if( col >= m->cols || row >= m->rows )
return -1;
m->data[ m->cols * row + col ] = val;
return 0;
}
int matrix_get( struct matrix * m, int row, int col, int * val)
{
if( col >= m->cols || row >= m->rows )
return -1;
else
{
*val = m->data[ m->cols * row + col ];
return 0;
}
}
void print_matrix( struct matrix * m )
{
int r,c;
int val;
for( r = 0; r < m->rows; r++ )
{
for( c = 0; c < m->cols; c++ )
{
matrix_get( m, r, c, &val );
printf( "%5d%s", val, c + 1 < m->cols ? "," : "" );
}
printf("\n");
}
}
int main (int argc, char **argv)
{
int r,c;
struct matrix * m = new_matrix( 5, 5 );
for( r = 0; r < m->rows; r++ )
{
for( c = 0; c < m->cols; c++ )
{
matrix_set( m, r, c, (r +1)* 10 + c + 1 );
}
}
print_matrix( m );
free_matrix( m );
return 0;
}
person
Brian McFarland
schedule
04.05.2012