Перейти к содержанию

Лекция 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 — это мощный инструмент для хранения и обработки данных. Они позволяют эффективно управлять памятью, использовать арифметику указателей и выполнять широкий спектр операций. Понимание работы массивов — это основа для изучения более сложных структур данных и алгоритмов.


Моя страсть к массивам мне очень нравится
Пишу массивы, и они повторяются
Люблю смотреть, как ошибки из них осыпаются
Пишу массивы, и они повторяются