Лекция 13: Двумерные массивы
"Я не боюсь того, кто учит 10 тысячам строкам кода на C
Я боюсь геморроидального узла"
— Уильям Дефо
Введение в двумерные массивы
Массив — это структура данных, состоящая из элементов одного типа, которые хранятся последовательно в памяти.
Одномерные массивы представляют линейные структуры данных (например, векторы), тогда как двумерные массивы используются для работы с более сложными структурами данных, такими как матрицы, таблицы или экраны.
В языке C двумерный массив — это по сути массив одномерных массивов, где каждый элемент массива имеет два индекса: номер строки и номер столбца.
О понятии двумерного массива
В общем случае, двумерный массив — понятие гораздо более широкое, чем матрица, поскольку он может быть и не прямоугольным, и не числовым.
Объявление двумерных массивов
Двумерный массив объявляется следующим образом:
<тип данных> <имя массива>[количество строк][количество столбцов];
Пример:
int matrix[3][4];
Здесь matrix
— массив целых чисел, состоящий из 3 строк и 4 столбцов.
- Первый индекс указывает номер строки.
- Второй индекс — номер столбца.
Примечание
В C индексы начинаются с 0.
Инициализация двумерных массивов
Двумерные массивы можно инициализировать сразу при объявлении:
int matrix[2][2] = {{1, 2}, {3, 4}};
Также можно инициализировать массив, опуская первый размер:
int matrix[][2] = {{1, 2}, {3, 4}};
Компилятор определит размерность массива, исходя из количества элементов.
Доступ к элементам массива
Элементы массива можно изменять и читать по индексам:
matrix[1][1] = 5; // Записывает значение 5 во второй строке, втором столбце
int value = matrix[0][1]; // Читает значение из первой строки, второго столбца
Работа с массивами с помощью циклов
Для обработки всех элементов двумерного массива удобно использовать вложенные циклы:
const int rows = 3;
const int cols = 4;
int matrix[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
matrix[i][j] = i * j; // Пример заполнения массива
}
}
Здесь внешний цикл проходит по строкам, а внутренний — по столбцам каждой строки.
Низкоуровневая абстракция
В языке C массивы по сути являются указателями на свой первый элемент. Например, для двумерного массива matrix[3][4]
имя matrix
указывает на начало первой строки. Элементы можно также получать через указательную арифметику:
*(*(matrix + i) + j); // Эквивалент matrix[i][j]
Каждый элемент двумерного массива хранится последовательно в памяти. Адрес элемента matrix[i][j]
вычисляется по формуле:
Пример представления массива в памяти
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
Адрес | Значение | Индексы |
---|---|---|
0x100 | 1 | matrix[0][0] |
0x104 | 2 | matrix[0][1] |
0x108 | 3 | matrix[0][2] |
0x10C | 4 | matrix[0][3] |
0x110 | 5 | matrix[1][0] |
0x114 | 6 | matrix[1][1] |
0x118 | 7 | matrix[1][2] |
0x11C | 8 | matrix[1][3] |
0x120 | 9 | matrix[2][0] |
0x124 | 10 | matrix[2][1] |
0x128 | 11 | matrix[2][2] |
0x12C | 12 | matrix[2][3] |
Каждый элемент занимает 4 байта, и адрес следующего увеличивается на 4 байта. Адрес matrix[i][j]
рассчитывается по формуле:
Например, элемент matrix[2][1]
будет по адресу:
Это пример построчного размещения: элементы массива идут подряд, строка за строкой, начиная с первой.
Примеры операций с массивами
Сумма всех элементов
int sum = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
sum += matrix[i][j];
}
}
Заполнение массива случайными числами
#include <stdlib.h>
#include <time.h>
srand(time(NULL)); // Инициализация генератора случайных чисел
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
matrix[i][j] = rand() % 10; // Случайное число от 0 до 9
}
}
Сумма элементов главной диагонали
int sum = 0;
for (int i = 0; i < N; i++) {
sum += matrix[i][i];
}
Перестановка строк
for (int j = 0; j < cols; j++) {
int temp = matrix[1][j];
matrix[1][j] = matrix[3][j];
matrix[3][j] = temp;
}
Сортировка методом пузырька
for (int i = 0; i < rows * cols - 1; i++) {
for (int j = 0; j < rows * cols - i - 1; j++) {
if (matrix[j / cols][j % cols] > matrix[(j + 1) / cols][(j + 1) % cols]) {
int temp = matrix[j / cols][j % cols];
matrix[j / cols][j % cols] = matrix[(j + 1) / cols][(j + 1) % cols];
matrix[(j + 1) / cols][(j + 1) % cols] = temp;
}
}
}
Применение двумерных массивов
- Графика и таблицы: Хранение значений для графического интерфейса, например, пикселей изображения.
- Матрицы в линейной алгебре: Операции над матрицами, такие как сложение, умножение и нахождение детерминанта.
- Игровые доски: Хранение состояния, например, шахматной доски.
Заключение
Двумерные массивы — мощный инструмент для организации данных в языке C. Они позволяют эффективно обрабатывать данные, хранящиеся в табличном формате, и активно используются в графике, вычислениях и других областях программирования.