Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Необходимо заполнить матрицу MxN числами по спирали
- #include <stdio.h>
- #include <string.h> // memset
- #include <stdlib.h> // malloc, strtoul
- #include <errno.h> // Для обработки ошибок преобразования строки в число
- #define M 5 // Ширина
- #define N 4 // Высота
- // Состояние конечного автомата
- #define STATE_RIGHT 0
- #define STATE_DOWN 1
- #define STATE_LEFT 2
- #define STATE_UP 3
- //-------------------------------------------------------------------
- // Прототипы функций
- //-------------------------------------------------------------------
- // Выделяет память под массив matrix_buf, в котором будут храниться данные
- // матрицы размером width на height элементов и под массив указателей
- // на строки в массиве matrix_buf
- // Возвращает указатели на выделенную память или NULL при неудаче
- int** alloc_matrix( int** matrix_buf, size_t width, size_t height );
- // Заполняет матрицу шириной width и высотой height числами по спирали,
- // начиная с числа start_n. В каждой последующей ячейке start_n
- // увеличивается на единицу
- void fill_matrix( int** m, size_t width, size_t height, int start_n );
- // Выводит матрицу в stdout
- void show_matrix( int** m, size_t width, size_t height );
- // Преобразует число в виде строки в unsigned long
- // Возвращает 1 в случае успеха и 0 при неудаче
- int str_to_ulong( char* str, unsigned long* ul );
- //-------------------------------------------------------------------
- //-------------------------------------------------------------------
- // Реализация функций
- //-------------------------------------------------------------------
- void fill_matrix( int** m, size_t width, size_t height, int start_n )
- {
- // Нам нужно заполнить не более чем width * height ячеек
- size_t max = width * height;
- // Количество заполненных ячеек
- size_t count = 0;
- size_t state = STATE_RIGHT;
- size_t x = 0;
- size_t min_x = 0;
- size_t max_x = width - 1;
- size_t y = 0;
- size_t min_y = 0;
- size_t max_y = height - 1;
- while( count < max )
- {
- m[y][x] = start_n;
- switch( state )
- {
- // Движемся слева на право
- case STATE_RIGHT:
- if( x == max_x)
- {
- state = STATE_DOWN;
- min_y++;
- y++;
- }
- else
- {
- x++;
- }
- start_n++;
- count++;
- break;
- case STATE_DOWN:
- if( y == max_y )
- {
- state = STATE_LEFT;
- x--;
- max_x--;
- }
- else
- {
- y++;
- }
- start_n++;
- count++;
- break;
- case STATE_LEFT:
- if( x == min_x )
- {
- state = STATE_UP;
- y--;
- max_y--;
- }
- else
- {
- x--;
- }
- start_n++;
- count++;
- break;
- case STATE_UP:
- if( y == min_y )
- {
- state = STATE_RIGHT;
- x++;
- min_x++;
- }
- else
- {
- y--;
- }
- start_n++;
- count++;
- break;
- }
- }
- }
- //-------------------------------------------------------------------
- void show_matrix( int** m, size_t width, size_t height )
- {
- size_t max = width* height;
- int column_width = 1;
- // Вычислим максимальное количество цифр, которое нам понадобится
- while( max >=10 )
- {
- max = max / 10;
- column_width++;
- }
- printf("Матрица %lux%lu\n", width, height );
- for( size_t y = 0; y < height; y++ )
- {
- for( size_t x = 0; x < width; x++ )
- {
- //printf( "[%02d]", m[y][x] );
- printf( "[%0*d]", column_width, m[y][x] );
- }
- printf("\n");
- }
- }
- //-------------------------------------------------------------------
- int** alloc_matrix( int** matrix_buf, size_t width, size_t height )
- {
- // Массив для хранения данных матрицы MxN
- int* matrix;
- // Матрица width * height
- int** m = NULL;
- // Очистим память
- *matrix_buf = NULL;
- // Выделим память под буфер для хранения данных матрицы
- matrix = (int*)malloc( sizeof(int) * width * height );
- if( matrix )
- {
- // Очистим память для хранения данных матрицы
- memset( matrix, 0, sizeof(int)* width * height );
- // Выделим память под массив указателей на строки матрицы
- m = (int**)malloc( sizeof(int*) * height );
- if( m )
- {
- // Заполним массив указателей адресами начала строк матрицы
- for( int i = 0; i < height; i++ )
- {
- m[i] = &matrix[ i * width ];
- }
- }
- else
- {
- free( matrix );
- matrix = NULL;
- perror("malloc:");
- }
- // Сохраним указатель на буфер с данными матрицы
- *matrix_buf = matrix;
- }
- else
- {
- perror("malloc:");
- }
- return m;
- }
- //-------------------------------------------------------------------
- // Преобразует число в виде строки в unsigned long
- // Возвращает 1 в случае успеха и 0 при неудаче
- int str_to_ulong( char* str, unsigned long* ul )
- {
- int result = 0;
- // Остаток строки
- char* tail;
- unsigned long n;
- // Очистим мусор
- *ul = 0;
- errno = 0;
- // Попытаемся преобразовать строку в число
- n = strtoul( str, &tail, 0 );
- if( errno == 0 )
- {
- if( *tail == '\0' )
- {
- *ul = n;
- result++;
- }
- else
- {
- if( tail == str )
- {
- fprintf(stderr, "Строка '%s' не является числом!\n", str);
- }
- else
- {
- fprintf(stderr, "В строке '%s' обнаружен мусор '%s'!\n",
- str, tail );
- }
- }
- }
- else
- {
- perror( "strtoul:" );
- }
- return result;
- }
- //-------------------------------------------------------------------
- //-------------------------------------------------------------------
- int main( int argc, char* argv[] )
- {
- // Массив для хранения данных матрицы MxN
- int* matrix;
- // Матрица MxN
- int** m;
- // Ширина матрицы
- size_t width;
- // Высота матрицы
- size_t height;
- unsigned long start_n = 0;
- if( argc > 2 )
- {
- if( argc > 3 )
- {
- if( !str_to_ulong( argv[3], &start_n ) )
- {
- fprintf(stderr,
- "Будет использовано начальное значение по умолчанию!\n");
- }
- }
- if(str_to_ulong(argv[1], &width) && str_to_ulong(argv[2], &height))
- {
- // Попытаемся выделить память под матрицу
- m = alloc_matrix( &matrix, width, height );
- if( m && matrix )
- {
- printf( "Спиральное заполнение матрицы "
- "возрастающими числами начиная с %lu:\n", start_n );
- fill_matrix( m, width, height, start_n );
- show_matrix( m, width, height );
- free( m );
- free( matrix );
- }
- }
- }
- else
- {
- printf( "Программа заполняет матрицу по спирали числами\n" );
- printf( "Использование:\n" );
- printf( "%s ширина высота [начальное_число]\n", argv[0] );
- }
- return 0;
- }
- //-------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement