Загрузка данных


#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 100

/* ----------------------------------------------------------
 * Вспомогательные функции
 * ---------------------------------------------------------- */

/* Вывести матрицу: в конце строки нет лишних пробелов,
 * после последней строки нет символа перевода строки */
static void print_matrix(int **mat, int rows, int cols) {
    int i, j;
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            if (j > 0) putchar(' ');
            printf("%d", mat[i][j]);
        }
        if (i < rows - 1) putchar('\n');
    }
}

/* Прочитать элементы матрицы */
static int read_matrix(int **mat, int rows, int cols) {
    int i, j;
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            if (scanf("%d", &mat[i][j]) != 1) {
                return -1;
            }
        }
    }
    return 0;
}

/* ----------------------------------------------------------
 * Реализация четырёх способов выделения
 * ---------------------------------------------------------- */

/* 1. Статическое (локальный массив на стеке) */
static int use_static(int rows, int cols) {
    int s_matrix[MAX_SIZE][MAX_SIZE];
    int **mat;
    int *row_ptrs[MAX_SIZE];
    int i, j;

    if (rows > MAX_SIZE || cols > MAX_SIZE) return -1;

    /* Заполняем массив указателей на строки */
    for (i = 0; i < rows; i++) {
        row_ptrs[i] = s_matrix[i];
    }
    mat = row_ptrs;

    if (read_matrix(mat, rows, cols) != 0) return -1;
    print_matrix(mat, rows, cols);
    return 0;
}

/* 2. Массив указателей + malloc на каждую строку */
static int use_dynamic1(int rows, int cols) {
    int **mat;
    int i;

    mat = malloc(rows * sizeof(int *));
    if (!mat) return -1;
    for (i = 0; i < rows; i++) {
        mat[i] = malloc(cols * sizeof(int));
        if (!mat[i]) {
            int k;
            for (k = 0; k < i; k++) free(mat[k]);
            free(mat);
            return -1;
        }
    }

    if (read_matrix(mat, rows, cols) != 0) {
        for (i = 0; i < rows; i++) free(mat[i]);
        free(mat);
        return -1;
    }
    print_matrix(mat, rows, cols);

    for (i = 0; i < rows; i++) free(mat[i]);
    free(mat);
    return 0;
}

/* 3. Один блок памяти: указатели в начале, данные — следом */
static int use_dynamic2(int rows, int cols) {
    int **mat;
    int *data;
    int i;
    size_t ptr_size = rows * sizeof(int *);
    size_t data_size = rows * cols * sizeof(int);

    mat = malloc(ptr_size + data_size);
    if (!mat) return -1;
    data = (int *)((char *)mat + ptr_size);
    for (i = 0; i < rows; i++) {
        mat[i] = data + i * cols;
    }

    if (read_matrix(mat, rows, cols) != 0) {
        free(mat);
        return -1;
    }
    print_matrix(mat, rows, cols);

    free(mat);
    return 0;
}

/* 4. Один блок памяти: данные лежат сразу за массивом указателей */
static int use_dynamic3(int rows, int cols) {
    int **mat;
    int *data;
    int i;
    size_t ptr_size = rows * sizeof(int *);
    size_t data_size = rows * cols * sizeof(int);

    mat = malloc(ptr_size + data_size);
    if (!mat) return -1;
    data = (int *)(mat + rows);
    for (i = 0; i < rows; i++) {
        mat[i] = data + i * cols;
    }

    if (read_matrix(mat, rows, cols) != 0) {
        free(mat);
        return -1;
    }
    print_matrix(mat, rows, cols);

    free(mat);
    return 0;
}

/* ----------------------------------------------------------
 * Главная функция
 * ---------------------------------------------------------- */

int main(void) {
    int choice;
    int rows, cols;
    int result = -1;

    if (scanf("%d", &choice) != 1) {
        printf("n/a\n");
        return 0;
    }
    if (choice < 1 || choice > 4) {
        printf("n/a\n");
        return 0;
    }

    if (scanf("%d %d", &rows, &cols) != 2) {
        printf("n/a\n");
        return 0;
    }
    if (rows <= 0 || cols <= 0) {
        printf("n/a\n");
        return 0;
    }
    if (choice == 1 && (rows > MAX_SIZE || cols > MAX_SIZE)) {
        printf("n/a\n");
        return 0;
    }

    switch (choice) {
        case 1: result = use_static(rows, cols); break;
        case 2: result = use_dynamic1(rows, cols); break;
        case 3: result = use_dynamic2(rows, cols); break;
        case 4: result = use_dynamic3(rows, cols); break;
    }

    if (result != 0) {
        printf("n/a\n");
    }

    return 0;
}