Массивы

Объявление массива


Массив (array) – это совокупность переменных одного типа, к которым можно обратиться с помощью общего имени и индекса, т.е. номера элемента в массиве. По сути это набор переменных, которые называются одним именем и имеют личные номера. Для объявления массива достаточно указать квадратные скобки после имени переменной с любым типом данных.

Указать компилятору размер массива можно двумя способами: явным числом в квадратных скобках, либо при объявлении записать в каждую ячейку значение, тогда компилятор сам посчитает их количество. Рассмотрим пример объявления массива разными способами:

// указываем количество ячеек
byte myInts[6];

// указываем содержимое ячеек, компилятор сам посчитает их количество
int myPins[] = {2, 4, 8, 3, 6,};

// указываем и то и то, количество ячеек в [ ] должно совпадать с { } или быть больше!
float Sens[3] = {0.2, 0.4, -8.5};

// храним символы
char message[6] = {'h', 'e', 'l', 'l', 'o'};
  • Размер массива, объявленного глобально, должен быть задан однозначно: конкретным числом, константой const или константой #define, так как массив будет существовать на всём протяжении работы программы и не может менять свой размер.
  • Размер массива, объявленного локально, может быть задан переменной, так как такой массив создаётся во время выполнения программы и удаляется из памяти после закрывающей фигурной скобки.
  • После указания последнего элемента массива можно ставить запятую, компилятор её проигнорирует (см. пример выше, массив myPins).
  • Массив символов является строкой, о них мы поговорим в отдельном уроке.
// размеры
#define arr1_size 10
const byte arr2_size = 20;
byte arr3_size = 30;

// массивы
int arr0[5];
int arr1[arr1_size];
int arr2[arr2_size];
//int arr3[arr3_size];    // приведёт к ошибке!

Обращение к элементам


Обращение к элементу массива осуществляется точно так же, в квадратных скобках. Важно помнить, что отсчёт в программировании начинается с нуля, и первый элемент массива имеет номер 0 (ноль):

// первый элемент массива myInts равен 50 
myInts[0] = 50;

// записать в ячейку 3 массива myPins
// значение элемента 0 массива myInts
myPins[3] = myInts[0];

Размер массива


Для определения размера массива можно воспользоваться функцией sizeof(), которая вернёт размер массива в количестве байтов. Зачем? Допустим в программе массив задаётся без указания размера, но элементы задаются явно (в фигурных скобках) и в процессе разработки программы размер массива может меняться. Чтобы не пересчитывать размер вручную и не менять его везде в программе, можно использовать эту функцию.

Примечание: если размер массива неизвестен на момент компиляции программы – sizeof() не сможет его посчитать и выдаст размер указателя (2 байта на AVR).

Ещё один момент: sizeof(имя_массива) даёт вес массива, а не количество элементов в нём! Если массив состоит из элементов типа byte – его вес совпадёт с размером. В остальных случаях нужно разделить вес массива на вес одного элемента, например так: sizeof(arr) / sizeof(arr[0]) – делим на вес элемента, чтобы не привязываться к типам данных. Результат вычисляется на этапе компиляции и в процессе работы программы время на вычисление не тратится.

Многомерные массивы


Выше мы рассмотрели одномерные массивы, в которых элементы определяются просто порядковым номером (индексом). Можно задавать и многомерные массивы, в которых адрес элемента будет определяться несколькими индексами. Например двумерный массив, он же матрица, он же таблица, каждый элемент имеет номер строки и столбца. Задаётся такой массив следующим образом: тип имя[строки][столбцы]

// двумерный массив, 5 строк 10 столбцов
byte myArray[5][10];

// матрица 3х4
byte myMatrix[][4] = {
  {10, 11, 12, 13},
  {14, 15, 16, 17},
  {18, 19, 20, 21},
};

// матрица 2х3
byte myTable[][3] = {{10, 11, 12}, {13, 14, 15}};

Очень важно помнить, что при объявлении массива с вручную вписанными данными нужно обязательно указать размер количества ячеек в измерении на 1 меньше размерности массива (для двумерного – обязательно указать размер одного из измерений, для трёхмерного – два, и т.д.).

В рассмотренном выше двумерном массиве myMatrix элемент с адресом 0, 2 (строка 0 столбец 2) имеет значение 12. Обращение к этому элементу например с целью перезаписи будет выглядеть так:

// меняем 12 на 20, ячейка 0,2
myMatrix[0][2] = 20;

С элементами массивов можно производить такие же действия, как с обычными переменными, т.е. всю математику, которую мы рассматривали в предыдущем уроке. Также не стоит забывать, что массивом может быть почти любой тип данных: численные переменные, структуры, классы, строки… Область видимости точно так же применяется к массивам, ведь массив – это по сути обычная переменная.

Функции для работы с массивами


В C++ есть несколько полезных функций для работы с массивами:

  • memset(buf, val, len) – заполнить байтовый массив buf длиной len значением val 
  • memcmp(buf1, buf2, len) – сравнить массивы buf1 и buf2 на длину len. Вернёт 0 если массивы одинаковые
  • memcpy(dest, src, len) – скопировать массив src в массив dest на длину len

Пример:

byte src[5] = {1, 2, 3, 4, 5};
// src == {1, 2, 3, 4, 5}

byte dst[5];  // "пустой" массив
memset(dst, 123, 5);  // заполнить dst значением 123
// dst == {123, 123, 123, 123, 123}

// сравнить
Serial.println(memcmp(src, dst, 5) == 0); // false

// скопировать из src в dst
memcpy(dst, src, 5);
// dst == {1, 2, 3, 4, 5}

// сравнить
Serial.println(memcmp(src, dst, 5) == 0); // true

Видео


Полезные страницы


4.4/5 - (19 голосов)
Подписаться
Уведомить о
guest

18 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии