Назначение не является простым для новичка.
Для начинающих это плохая идея, когда используются глобальные переменные, такие как start
, а определения функций зависят от глобальных переменных.
Например, Вы не можете определить в своей программе более одной матрицы.
Внутри функции arrToMatrix
вам приходится иметь дело с указателями на указатели. В противном случае функция будет более сложной или запуск указателя не изменится, поскольку изменение локальных переменных col и row в вашей программе не влияет на i = на начало указателя. И, кроме того, например, в этом фрагменте кода
ptr = malloc(sizeof(matrix));
ptr->data = a[i][j];
ptr->next = NULL;
ptr->down = NULL;
if(row == col)
row = ptr;
имеется избыточное распределение узла, когда i равно 0, а j равно 0.
В начале функции текущая матрица, указанная указателем головы, должна быть освобождена. В противном случае возможны утечки памяти, и пользователь не сможет переназначить матрицу с другим массивом.
Поэтому вам нужно написать еще одну функцию, которая освобождает всю выделенную память для текущей матрицы.
Вот демонстрационная программа, которая показывает, как функции могут быть реализованы. В программе есть закомментированная функция matrixDisplay
, используемая для тестирования. Вы можете запустить его вместо функции без комментариев matrixDisplay
, чтобы увидеть, как определяется список и его ссылки.
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *next;
struct node *down;
} matrix;
void deleteMatrix( matrix **head )
{
if ( *head != NULL )
{
for ( matrix *row = ( *head )->next; row != NULL; )
{
while ( row != NULL )
{
matrix *tmp = row;
row = row->next;
free( tmp );
}
row = ( *head )->down;
if ( ( *head )->down != NULL )
{
( *head )->down = row->down;
}
}
free( *head );
*head = NULL;
}
}
void arrToMatrix( matrix **head, size_t m, size_t n, int a[m][n] )
{
deleteMatrix( head );
matrix **row = head;
for ( size_t i = 0; i < m; i++ )
{
matrix **column = row;
for ( size_t j = 0; j < n; j++ )
{
*column = malloc( sizeof( matrix ) );
( *column )->data = a[i][j];
( *column )->down = NULL;
( *column )->next = NULL;
column = &( *column )->next;
}
row = &( *row )->down;
}
row = head;
for ( size_t i = 0; i + 1 < m; i++ )
{
matrix *column = *row;
matrix *next_row_column = ( *row )->down;
for ( size_t j = 0; j < n; j++ )
{
column->down = next_row_column;
column = column->next;
next_row_column = next_row_column->next;
}
row = &( *row )->down;
}
}
void matrixDisplay( const matrix *head )
{
for ( ; head != NULL; head = head->down )
{
for ( const matrix *column = head; column != NULL; column = column->next )
{
printf( "%2d ", column->data );
}
putchar( '\n' );
}
}
/*
void matrixDisplay( const matrix *head )
{
for ( ; head != NULL; head = head->down )
{
for ( const matrix *column = head; column != NULL; column = column->next )
{
printf( "%2d ( %p ): next( %p ), down( %p ) ",
column->data, ( void * )column, ( void * )column->next, ( void * )column->down );
}
putchar( '\n' );
}
}
*/
int main(void)
{
enum { N = 3 };
int a[][N] =
{
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 }
};
matrix *head = NULL;
arrToMatrix( &head, N, N, a );
matrixDisplay( head );
putchar( '\n' );
deleteMatrix( &head );
return 0;
}
Вывод программы:
1 2 3
4 5 6
7 8 9
Вывод прокомментированная функция matrixDisplay может выглядеть, например, следующим образом.
1 ( 0x558b577e7260 ): next( 0x558b577e7280 ), down( 0x558b577e72c0 ) 2 ( 0x558b577e7280 ): next( 0x558b577e72a0 ), down( 0x558b577e72e0 ) 3 ( 0x558b577e72a0 ): next( (nil) ), down( 0x558b577e7300 )
4 ( 0x558b577e72c0 ): next( 0x558b577e72e0 ), down( 0x558b577e7320 ) 5 ( 0x558b577e72e0 ): next( 0x558b577e7300 ), down( 0x558b577e7340 ) 6 ( 0x558b577e7300 ): next( (nil) ), down( 0x558b577e7360 )
7 ( 0x558b577e7320 ): next( 0x558b577e7340 ), down( (nil) ) 8 ( 0x558b577e7340 ): next( 0x558b577e7360 ), down( (nil) ) 9 ( 0x558b577e7360 ): next( (nil) ), down( (nil) )