Лекция 10: Одномерные массивы
"Массивы в C — это как аренда квартиры без замков: никто не следит за границами, и если что-то сломается, то это твоя проблема." - Конфуций
Понятие массива. Одномерные массивы
Массив — это структура данных, представляющая собой упорядоченную совокупность элементов одного типа. Каждый элемент массива доступен по индексу, который задается целым числом, начиная с нуля. Число элементов массива называется его размером.
Пример описания массива:
int m[20]; // массив из 20 элементов типа int
Основные свойства массивов
- Индексы массивов начинаются с 0.
- Описание массива включает квадратные скобки после имени, где указывается количество элементов.
- Размер массива должен быть определён константой или константным выражением.
- Массивы в C не имеют встроенного механизма контроля выхода за границы, что может приводить к ошибкам.
Пример инициализации массива:
int ages[5] = {18, 21, 25, 30, 40};
int ages[5] = {18, 21}; // элементы ages[2], ages[3], ages[4] инициализированы нулями
Представление массива в памяти
Массивы в языке C хранятся в памяти как единый блок. Элементы массива занимают последовательные ячейки памяти, размер которых зависит от типа данных массива.
Пример представления массива:
int numbers[5] = {10, 20, 30, 40, 50};
Индекс | Значение | Адрес |
---|---|---|
0 | 10 | 0x100 |
1 | 20 | 0x104 |
2 | 30 | 0x108 |
3 | 40 | 0x10C |
4 | 50 | 0x110 |
Адрес элемента вычисляется по формуле: начальный адрес + индекс * размер_элемента
.
Работа с указателями
Имя массива является указателем на первый элемент. Это позволяет использовать указатели для доступа к элементам массива.
Пример работы с указателями:
int numbers[3] = {10, 20, 30};
int *p = numbers; // указатель на первый элемент массива
printf("%d", *p); // выводит numbers[0]
printf("%d", *(p + 1)); // выводит numbers[1]
Использование указателей для обработки массивов
Элементы массива можно обрабатывать с помощью арифметики указателей. Например:
int nums[5] = {1, 2, 3, 4, 5};
int *start = nums;
int *end = nums + 4;
while (start < end) {
int temp = *start;
*start = *end;
*end = temp;
start++;
end--;
}
Операция индексирования
Индексирование в C эквивалентно разыменованию указателя с добавлением смещения. Например:
numbers[2] // то же самое, что *(numbers + 2)
Интересный факт: 17[numbers]
в C эквивалентно numbers[17]
, однако такой подход не рекомендуется использовать.
Строки как массивы символов
Строка в C — это одномерный массив символов, завершающийся нуль-символом (\0
). Например:
char name[] = "Hello"; // строка занимает 6 байт (включая \0)
Для работы со строками используются стандартные функции:
strlen
— вычисляет длину строки (без учёта\0
).strcpy
— копирует содержимое одной строки в другую.strcat
— присоединяет одну строку к другой.strcmp
— сравнивает две строки.
Пример работы с строкой:
#include <stdio.h>
#include <string.h>
int main() {
char name[50];
printf("Введите имя: ");
scanf("%s", name);
printf("Ваше имя: %s\n", name);
printf("Длина имени: %d\n", (int)strlen(name));
return 0;
}
Примеры обработки массивов
- Увеличение всех элементов массива на 1:
int nums[3] = {1, 2, 3};
for (int i = 0; i < 3; i++) {
nums[i]++;
}
- Поиск минимального элемента массива:
int nums[5] = {5, 3, 8, 1, 4};
int min = nums[0];
for (int i = 1; i < 5; i++) {
if (nums[i] < min) {
min = nums[i];
}
}
printf("Минимальное значение: %d\n", min);
- Циклический сдвиг массива влево:
int nums[5] = {1, 2, 3, 4, 5};
int first = nums[0];
for (int i = 0; i < 4; i++) {
nums[i] = nums[i + 1];
}
nums[4] = first;
- Реверс массива с использованием указателей:
int nums[5] = {1, 2, 3, 4, 5};
int *start = nums;
int *end = nums + 4;
while (start < end) {
int temp = *start;
*start = *end;
*end = temp;
start++;
end--;
}
Массивы указателей
Массивы могут состоять из указателей. Например:
int *arr[10]; // массив из 10 указателей на int
Для работы с массивами указателей используются стандартные операции:
int var = 42;
arr[0] = &var;
printf("%d", *arr[0]); // выводит 42
Передача массивов в функции
Массивы передаются в функции в виде указателей. Это значит, что изменения в массиве внутри функции отразятся на исходном массиве.
Пример:
#include <stdio.h>
void doubleValues(int arr[], int size) {
for (int i = 0; i < size; i++) {
arr[i] *= 2;
}
}
int main() {
int nums[5] = {1, 2, 3, 4, 5};
doubleValues(nums, 5);
for (int i = 0; i < 5; i++) {
printf("%d ", nums[i]);
}
return 0;
}
Заключение
Одномерные массивы в C — это мощный инструмент для хранения и обработки данных. Они позволяют эффективно управлять памятью, использовать арифметику указателей и выполнять широкий спектр операций. Понимание работы массивов — это основа для изучения более сложных структур данных и алгоритмов.