Умножение двух матриц на C

CBeginner
Практиковаться сейчас

Введение

В этом лабораторном практикуме вы научитесь умножать две матрицы на языке C. Практикум охватывает следующие этапы:

Чтение Размеров и Элементов: Вы узнаете, как считывать размеры и элементы двух матриц из пользовательского ввода. Этот этап гарантирует, что матрицы совместимы для умножения.

Умножение Строк на Столбцы: Вы реализуете алгоритм умножения матриц, где каждый элемент матрицы произведения вычисляется путём умножения соответствующих строк и столбцов входных матриц.

Вывод Результирующей Матрицы: Наконец, вы отобразите полученную матрицу произведения.

По завершении этого практикума вы получите глубокое понимание умножения матриц на языке C и сможете применять его в различных приложениях.

Чтение Размеров и Элементов

В этом шаге вы узнаете, как читать размеры и элементы матриц для умножения матриц на языке C. Мы создадим программу, которая позволит пользователям вводить размер и значения двух матриц.

Сначала создадим новый файл C для нашей программы умножения матриц:

cd ~/project
nano matrix_multiply.c

Теперь добавим следующий код для чтения размеров матриц:

#include <stdio.h>

#define MAX_SIZE 100

int main() {
    int rows1, cols1, rows2, cols2;

    // Чтение размеров первой матрицы
    printf("Введите размеры первой матрицы (строки столбцы): ");
    scanf("%d %d", &rows1, &cols1);

    // Чтение размеров второй матрицы
    printf("Введите размеры второй матрицы (строки столбцы): ");
    scanf("%d %d", &rows2, &cols2);

    // Проверка возможности умножения матриц
    if (cols1 != rows2) {
        printf("Умножение матриц невозможно!\n");
        return 1;
    }

    printf("Размеры матриц подходят для умножения.\n");

    return 0;
}

Компилируем и запускаем программу:

gcc matrix_multiply.c -o matrix_multiply
./matrix_multiply

Пример вывода:

Введите размеры первой матрицы (строки столбцы): 2 3
Введите размеры второй матрицы (строки столбцы): 3 2
Размеры матриц подходят для умножения.

Рассмотрим код:

  • Мы определяем MAX_SIZE как 100, чтобы ограничить размеры матриц
  • scanf() используется для чтения размеров матриц из пользовательского ввода
  • Мы проверяем возможность умножения матриц, сравнивая столбцы первой матрицы со строками второй матрицы
  • Если размеры несовместимы, программа выводит сообщение об ошибке

Теперь изменим код для чтения элементов матриц:

#include <stdio.h>

#define MAX_SIZE 100

int main() {
    int rows1, cols1, rows2, cols2;
    int matrix1[MAX_SIZE][MAX_SIZE];
    int matrix2[MAX_SIZE][MAX_SIZE];

    // Чтение размеров первой матрицы
    printf("Введите размеры первой матрицы (строки столбцы): ");
    scanf("%d %d", &rows1, &cols1);

    // Чтение размеров второй матрицы
    printf("Введите размеры второй матрицы (строки столбцы): ");
    scanf("%d %d", &rows2, &cols2);

    // Проверка возможности умножения матриц
    if (cols1 != rows2) {
        printf("Умножение матриц невозможно!\n");
        return 1;
    }

    // Чтение элементов первой матрицы
    printf("Введите элементы первой матрицы:\n");
    for (int i = 0; i < rows1; i++) {
        for (int j = 0; j < cols1; j++) {
            printf("Введите элемент [%d][%d]: ", i, j);
            scanf("%d", &matrix1[i][j]);
        }
    }

    // Чтение элементов второй матрицы
    printf("Введите элементы второй матрицы:\n");
    for (int i = 0; i < rows2; i++) {
        for (int j = 0; j < cols2; j++) {
            printf("Введите элемент [%d][%d]: ", i, j);
            scanf("%d", &matrix2[i][j]);
        }
    }

    printf("Матрицы успешно считаны.\n");

    return 0;
}

Компилируем и запускаем программу:

gcc matrix_multiply.c -o matrix_multiply
./matrix_multiply

Пример вывода:

Введите размеры первой матрицы (строки столбцы): 2 3
Введите размеры второй матрицы (строки столбцы): 3 2
Введите элементы первой матрицы:
Введите элемент [0][0]: 1
Введите элемент [0][1]: 2
Введите элемент [0][2]: 3
Введите элемент [1][0]: 4
Введите элемент [1][1]: 5
Введите элемент [1][2]: 6
Введите элементы второй матрицы:
Введите элемент [0][0]: 7
Введите элемент [0][1]: 8
Введите элемент [1][0]: 9
Введите элемент [1][1]: 10
Введите элемент [2][0]: 11
Введите элемент [2][1]: 12
Матрицы успешно считаны.

Умножение Строк на Столбцы

В этом шаге вы узнаете, как выполнять умножение матриц, перемножая строки первой матрицы на столбцы второй матрицы. Мы продолжим работу над предыдущим кодом, чтобы реализовать алгоритм умножения матриц.

Обновите файл matrix_multiply.c, добавив функциональность умножения матриц:

cd ~/project
nano matrix_multiply.c

Замените предыдущий код следующим реализацией:

#include <stdio.h>

#define MAX_SIZE 100

int main() {
    int rows1, cols1, rows2, cols2;
    int matrix1[MAX_SIZE][MAX_SIZE];
    int matrix2[MAX_SIZE][MAX_SIZE];
    int result[MAX_SIZE][MAX_SIZE];

    // Чтение размеров первой матрицы
    printf("Введите размеры первой матрицы (строки столбцы): ");
    scanf("%d %d", &rows1, &cols1);

    // Чтение размеров второй матрицы
    printf("Введите размеры второй матрицы (строки столбцы): ");
    scanf("%d %d", &rows2, &cols2);

    // Проверка возможности умножения матриц
    if (cols1 != rows2) {
        printf("Умножение матриц невозможно!\n");
        return 1;
    }

    // Чтение элементов первой матрицы
    printf("Введите элементы первой матрицы:\n");
    for (int i = 0; i < rows1; i++) {
        for (int j = 0; j < cols1; j++) {
            printf("Введите элемент [%d][%d]: ", i, j);
            scanf("%d", &matrix1[i][j]);
        }
    }

    // Чтение элементов второй матрицы
    printf("Введите элементы второй матрицы:\n");
    for (int i = 0; i < rows2; i++) {
        for (int j = 0; j < cols2; j++) {
            printf("Введите элемент [%d][%d]: ", i, j);
            scanf("%d", &matrix2[i][j]);
        }
    }

    // Умножение матриц
    for (int i = 0; i < rows1; i++) {
        for (int j = 0; j < cols2; j++) {
            result[i][j] = 0;
            for (int k = 0; k < cols1; k++) {
                result[i][j] += matrix1[i][k] * matrix2[k][j];
            }
        }
    }

    // Вывод результирующей матрицы
    printf("\nРезультирующая матрица:\n");
    for (int i = 0; i < rows1; i++) {
        for (int j = 0; j < cols2; j++) {
            printf("%d ", result[i][j]);
        }
        printf("\n");
    }

    return 0;
}

Компилируем и запускаем программу:

gcc matrix_multiply.c -o matrix_multiply
./matrix_multiply

Пример вывода:

Введите размеры первой матрицы (строки столбцы): 2 3
Введите размеры второй матрицы (строки столбцы): 3 2
Введите элементы первой матрицы:
... (ввод элементов матриц)
...

Результирующая матрица:
58 64
139 154

Рассмотрим алгоритм умножения матриц:

  • Внешние циклы i и j перебирают элементы результирующей матрицы.
  • Внутренний цикл k выполняет скалярное произведение строки i первой матрицы и столбца j второй матрицы.
  • result[i][j] вычисляется путем суммирования произведений соответствующих элементов.
  • Вложенные циклы гарантируют правильное вычисление каждого элемента результирующей матрицы.

Ключевые моменты по умножению матриц:

  • Количество столбцов первой матрицы должно быть равно количеству строк второй матрицы.
  • Результирующая матрица будет иметь размеры (строки первой матрицы) × (столбцы второй матрицы).

Вывод Результирующей Матрицы

В этом заключительном шаге мы улучшим нашу программу умножения матриц, добавив более надежную функциональность вывода и обработку ошибок. Мы создадим функции для вывода матриц и улучшим общий пользовательский интерфейс.

Обновите файл matrix_multiply.c следующим улучшенным кодом:

cd ~/project
nano matrix_multiply.c

Замените предыдущий код этой расширенной версией:

#include <stdio.h>

#define MAX_SIZE 100

// Функция для вывода матрицы
void printMatrix(int matrix[MAX_SIZE][MAX_SIZE], int rows, int cols, const char* matrixName) {
    printf("\n%s Matrix:\n", matrixName);
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%5d ", matrix[i][j]);
        }
        printf("\n");
    }
}

int main() {
    int rows1, cols1, rows2, cols2;
    int matrix1[MAX_SIZE][MAX_SIZE];
    int matrix2[MAX_SIZE][MAX_SIZE];
    int result[MAX_SIZE][MAX_SIZE];

    // Чтение размеров первой матрицы
    printf("Введите размеры первой матрицы (строки столбцы): ");
    scanf("%d %d", &rows1, &cols1);

    // Чтение размеров второй матрицы
    printf("Введите размеры второй матрицы (строки столбцы): ");
    scanf("%d %d", &rows2, &cols2);

    // Проверка возможности умножения матриц
    if (cols1 != rows2) {
        printf("Умножение матриц невозможно!\n");
        printf("Количество столбцов первой матрицы (%d) должно быть равно количеству строк второй матрицы (%d).\n", cols1, rows2);
        return 1;
    }

    // Чтение элементов первой матрицы
    printf("Введите элементы первой матрицы:\n");
    for (int i = 0; i < rows1; i++) {
        for (int j = 0; j < cols1; j++) {
            printf("Введите элемент [%d][%d]: ", i, j);
            scanf("%d", &matrix1[i][j]);
        }
    }

    // Чтение элементов второй матрицы
    printf("Введите элементы второй матрицы:\n");
    for (int i = 0; i < rows2; i++) {
        for (int j = 0; j < cols2; j++) {
            printf("Введите элемент [%d][%d]: ", i, j);
            scanf("%d", &matrix2[i][j]);
        }
    }

    // Вывод исходных матриц
    printMatrix(matrix1, rows1, cols1, "Первая входная");
    printMatrix(matrix2, rows2, cols2, "Вторая входная");

    // Умножение матриц
    for (int i = 0; i < rows1; i++) {
        for (int j = 0; j < cols2; j++) {
            result[i][j] = 0;
            for (int k = 0; k < cols1; k++) {
                result[i][j] += matrix1[i][k] * matrix2[k][j];
            }
        }
    }

    // Вывод результирующей матрицы
    printMatrix(result, rows1, cols2, "Произведение");

    return 0;
}

Компилируем и запускаем программу:

gcc matrix_multiply.c -o matrix_multiply
./matrix_multiply

Пример вывода:

... (ввод размеров и элементов матриц)

Первая входная Matrix:
    1     2     3
    4     5     6

Вторая входная Matrix:
    7     8
    9    10
   11    12

Произведение Matrix:
   58    64
  139   154

Основные улучшения в этой версии:

  • Создана функция printMatrix() для вывода матриц с согласованным форматированием.
  • Добавлены более информативные сообщения об ошибках для совместимости умножения матриц.
  • Вывод исходных матриц перед выводом результирующей матрицы.
  • Используется %5d для выравнивания элементов матрицы.
  • Предоставлен понятный и читаемый формат вывода.

Описание функции вывода:

  • printMatrix() принимает матрицу, ее размеры и имя в качестве параметров.
  • Использует вложенные циклы для вывода каждого элемента.
  • Формат %5d гарантирует, что каждое число занимает 5 позиций для выравнивания.
  • Добавляет новую строку после каждой строки для лучшей читаемости.

Резюме

В этом лабораторном практикуме вы научитесь читать размеры и элементы матриц, а затем выполнять умножение матриц на языке C. Сначала вы узнаете, как читать размеры двух матриц и проверять их совместимость для умножения. Затем вы научитесь читать элементы двух матриц и хранить их в двумерных массивах. Наконец, вы узнаете, как выполнить фактическое умножение матриц и вывести результирующую матрицу произведения.