Работа с матрицами

/*
** Макрос для вычисления индекса элемента матрицы при одномерном представлении.
*/
#define EL(m, n_cols, row, col) \
    ((m)[(n_cols) * (row) + col])

/*
* Макрос, который предполагает наличие в контексте его вызова переменных
*  data и n_cols.
*/
#define EL2(row, col)  (data[n_cols * (row) + (col)])


// 1D матрицы
void how_to_use_1d_matrices()
{
    int n_rows, n_cols;                                      // размеры матрицы
    double *data = malloc(n_rows * n_cols * sizeof(double)); // элементы

    int row = 1, col = 0;

    data[row * n_cols + col] = 1.0;
    EL(data, n_cols, row, col) = 1.0;
    EL2(row, col) = 1.0; // ==> (data[n_cols * (row) + (col)])

    // Вызов функции: передаем размеры матрицы и указатель на данные.
    SLE(data, n_rows, n_cols, /* ... */);

    // Освобождение памяти
    free(data);
}
// +: связное хранение элементов в памяти
// -: медленная перестановка строк матрицы

// 2D - матрицы
void how_to_use_2d_matrices()
{
    int n_rows, n_cols; // размеры матрицы
    // Выделяем память под массив указателей ("массив массивов")
    double **matrix2d = malloc(n_rows * sizeof(double *));
    // Выделяем память под строки матрицы
    for (int row = 0; row < n_rows; row++)
    {
        matrix2d[row] = malloc(n_cols * sizeof(double));
    }

    // Присвоение значения элементу матрицы
    int row = 1, col = 0;
    matrix2d[row][col] = 1.0;
    // ...

    // Освобождаем память в обратном порядку
    for (int row = 0; row < n_rows; row++)
    {
        free(matrix2d[row]);
    }
    free(matrix2d);
}
// +: быстрая перестановка строк матрицы
// -: несвязное хранение элементов в памяти

// Комбинированный метод
void how_to_used_combined_approach()
{
    int n_rows = 10, n_cols = 20; // размеры матрицы
    double *data = malloc(n_rows * n_cols * sizeof(double));
    double **matrix2d = malloc(n_rows * sizeof(double *));
    for (int row = 0; row < n_rows; row++)
    {
        matrix2d[row] = data + (row * n_cols);
    }

    matrix2d[row][col] = 1.0;
    // ...

    // Освобождение памяти
    free(matrix2d);
    free(data);
}