Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- // Си работает "сверху вниз", поэтому мы не можем вызвать функцию, о которой нет информации
- // выше в файле. Чтобы не расставлять функции в файле в порядке их выполнения друг в друге,
- // используются так называемые "объявления функций". Это короткая запись функции, которая
- // описывает ее название, входные параметры и возвращаемый тип -- т.е., всю информацию, достаточную
- // для ее вызова (такая информация еще называется "сигнатурой функции"). Объявление функции предполагает, что где-то "внизу" по файлу будет и ее "определение" - то есть, сама функция с соответствующей объявлению сигнатурой.
- void print_matrix(int width, int height, int** matrix);
- void revert_rows_order(int height, int** matrix);
- int main() {
- int width, height;
- printf("Enter width of matrix: ");
- scanf("%d", &width);
- printf("\nEnter height of matrix: ");
- scanf("%d", &height);
- // Здесь, при выделении памяти, можно заметить два отличия от того способа,
- // которым я выделял память раньше.
- // Раньше я бы записал эту строчку так:
- // int** matrix = (int**)malloc(height * sizeof(int*);
- // Эта запись тоже корректна, но в ней (как я узнал) есть две небольшие помарки:
- // 1. Не рекомендуется явно приводить тип указателя, возвращаемого функцией malloc.
- // Причин этому несколько и они не особо просты для понимания, но суть в том,
- // что в Си, в отличие от C++, это делать не нужно.
- // Итог: в новой записи пропадает явное приведение типа: (int**) перед malloc.
- // 2. Рекомендуется вычислять размер элемента не при помощи типа, а при помощи значения.
- // Это еще менее понятная вещь, но суть тут в следующем:
- // Раньше я вычислял количество памяти так: брал количество элементов (height) и
- // умножал его на sizeof(int*). int* - это тип элемента, а sizeof(int*) вернет количество байт,
- // которое один элемент типа int* занимает на этом компьютереэ.
- // Однако sizeof можно вызвать не только на тип, но и на конкретную переменную.
- // При этом для такого вызова не нужно указывать скобки.
- // Новая запись выглядит так: sizeof *matrix.
- // Это означает, что я узнаю, сколько в байтах занимает один ТАКОЙ ЖЕ элемент (того же типа),
- // как тот, что я указал после sizeof. В данном случае я передаю *matrix, то есть
- // разыменовываю указатель matrix и получаю элемент типа int*.
- // Функционально это делает то же самое, что и старая запись, но выглядит более компактно
- // и более устойчиво к ошибкам. Например, если мы в будущем будем переписывать этот код и решим,
- // что нам нужна матрица не целых чисел, а дробных, нам будет достаточно поменять тип на float**
- // в начале строки, а внутри вызова malloc ничего менять уже будет не надо.
- int** matrix = malloc(height * sizeof *matrix);
- for (int i = 0; i < height; ++i) {
- int* row = malloc(width * sizeof *row);
- *(matrix + i) = row;
- }
- for (int i = 0; i < height; ++i) {
- for (int j = 0; j < width; ++j) {
- printf("\nEnter value at row %d, column %d: ", i + 1, j + 1);
- int value;
- scanf("%d", &value);
- *(*(matrix + i) + j) = value;
- }
- }
- printf("\nOriginal matrix:\n");
- print_matrix(width, height, matrix);
- revert_rows_order(height, matrix);
- printf("\nMatrix with rows reversed:\n");
- print_matrix(width, height, matrix);
- }
- // Вынес вывод массива на экран в отдельную функцию, чтобы не дублировать код
- void print_matrix(int width, int height, int** matrix) {
- for (int i = 0; i < height; ++i) {
- for (int j = 0; j < width; ++j) {
- printf("%d ", *(*(matrix + i) + j));
- }
- printf("\n");
- }
- }
- // Инверсия массива -- тривиальная задача, и один из известных алгоритмов ее решения
- // называется "метод двух указателей".
- // Я не вижу смысла подробно расписывать, как именно он работает, в интернете есть много статей
- // про него. Он не привязан к конкретному языку программирования, достаточно понять концепцию.
- void revert_rows_order(int height, int** matrix) {
- int** head = matrix;
- int** tail = matrix + height - 1;
- while (head < tail) {
- int* tail_temp = *tail;
- *tail = *head;
- *head = tail_temp;
- ++head;
- --tail;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment