• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Динамический массив пользовательского типа. Добавление, удаление ячеек. Делюсь опытом.

p-a-h-a

Member
Изучаю потихоньку язык. Разобрался с созданием динамического массива пользовательского типа. Научился вставлять ячейку в середину массива и удалять любую ячейку. Научился передавать массив в функцию и изменять его внутри функции по ссылкам и указателям.
На самом деле создается новый динамический массив в который копируется исходный со сдвигом в нужном месте, после чего исходный массив удаляется с заменой на новый массив.
Код:
typedef  struct data { //Тип структуры пользовательский
  uint32_t var1 = NULL;
  uint16_t var2 = NULL;
} data;
data *Array = nullptr; // Указатель типа data на будущий массив структур. Тип элементов массива может быть любым, например int
uint16_t lenght = 5;//Количество ячеек массива (структур).

void setup() {
  Serial.begin(115200);
  delay(2000);
  creatArr(Array, lenght); // Создаем массив на lenght ячеек.
  for (int i = 0; i < lenght; i++) {//Заполняем массив
    Array[i].var1 = i * 17;
    Array[i].var2 = i;
  }
  printArr(Array, lenght);// Выводим массив в serial
  addArrayCell(Array, lenght, 2); // Раздвигаем массив и добавляем ячейку на 2ю позицию
  printArr(Array, lenght);// Выводим массив в serial
  deleteArrayCell(Array, lenght, lenght-1);//Удаляем последнюю ячейку из массива структур Array
  printArr(Array, lenght);// Выводим массив в serial
}

void loop() {}

template<typename T1, typename T2>
void printArr(const T1* const &arr, T2 const &len) {
  for (T2 i = 0; i < len; i++) {
    Serial.printf("\nCell:%02u\t var1:%02u\t var2:%02u\t Free heap:%u\t", i, arr[i].var1, arr[i].var2, ESP.getFreeHeap());
  }
  Serial.print(F("\n---------------------------------------------\n"));
}

template<typename T1, typename T2, typename T3>
bool addArrayCell(T1* &arr, T2 &len, T3 num_of_Cell) { //Функция добавляет к массиву ячейку. Получаем ссылку на массив типа data*, получаем ссылку на длинну
  if (num_of_Cell > len) return false;
  data *local_arr = new T1[len + 1]; //Создаем локальный массив
  memcpy(local_arr, arr, sizeof(T1)*num_of_Cell); //Копируем исходный массив в локальный до места новой ячейки
  memcpy(local_arr + num_of_Cell + 1, arr + num_of_Cell, sizeof(arr[0]) * (len - num_of_Cell)); //Копируем после места новой ячейки
  data* oldarr = arr; //Создаем указатель на входящий массив
  arr = local_arr; //Присваиваем указателю входящего массива значение локального
  delete[] oldarr; //Удаляем что было во входящем массиве чтоб небыло утечки памяти
  len++;
  return true;
}

template<typename T1, typename T2, typename T3>
bool deleteArrayCell(T1* &arr, T2 &len, T3 num_of_Cell) {
  if (num_of_Cell >= len) return false;
  T1 *local_arr = new T1[len - 1];//Создаем локальный массив
  memcpy(local_arr, arr, sizeof(T1)*num_of_Cell); //Копируем исходный массив в локальный до места которое нужно удалить
  memcpy(local_arr + num_of_Cell, arr + num_of_Cell + 1, sizeof(arr[0]) * (len - num_of_Cell - 1)); //Копируем после места которое нужно удалить
  T1* oldarr = arr; //Создаем указатель на входящий массив
  arr = local_arr; //Присваиваем указателю входящего массива значение локального
  delete[] oldarr; //Удаляем что было во входящем массиве чтоб небыло утечки памяти
  len--;
  return true;
}

template<typename T1, typename T2>
void creatArr(T1* &arr, T2 const &len) {//
  T1 *local_arr = new T1[len];//Создаем локальный массив
  T1 *oldarr = arr;//Создаем указатель на входящий массив
  arr = local_arr;//Присваиваем указателю входящего массива значение локального
  delete [] oldarr;//Удаляем что было во входящем массиве чтоб небыло утечки памяти
}
1649937017445.png
 

p-a-h-a

Member
Скетч прилагаю.
Теория:
Шаблонные функции template<typename T1, typename T2> Видео
Указатели * Видео. Это плейлист. Следующие несколько видео тоже очень полезны.
Ссылки & Видео
Передача параметров в функцию по ссылке Видео
Динамический массив new int[10] Видео
 

Вложения

enjoynering

Well-known member
Вот это "динамического массива пользовательского типа" хорошо, но лучше сразу все термины дублировать и изучать на английском. Поверьте в будущем очень пригодится, тк все эти языки придуманы за рубежом и хороших книг на антимонгольском в 100500 раз больше чем на русском.
 

Сергей_Ф

Moderator
Команда форума
Сверху Снизу