ai-benchmark/tests/summarization/nuancesprog.ru_p_31317.txt
second_constantine 25e0a2a96a Remove "Лог файл" column from report
Remove the "Лог файл" (Log file) column from the report generation as it's no longer needed. This simplifies the report structure and removes unused functionality.
2026-01-26 22:40:44 +03:00

3 lines
11 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Динамические массивы  —  основа многих приложений на C++, это гибкое хранилище, которое расширяется вместе с данными. Изучим принцип работы этих массивов, как они создаются и когда используются в реальных сценариях. Создание простого динамического массива Вот базовая реализация с основными концепциями: template<typename T> class DynamicArray { private: T* data_; size_t size_; size_t capacity_; void resize(size_t new_capacity) { T* new_data = new T[new_capacity]; for (size_t i = 0; i < size_; ++i) { new_data[i] = std::move(data_[i]); } delete[] data_; data_ = new_data; capacity_ = new_capacity; } public: DynamicArray() : data_(new T[2]), size_(0), capacity_(2) {} ~DynamicArray() { delete[] data_; } void push_back(const T& value) { if (size_ == capacity_) { resize(capacity_ * 2); } data_[size_++] = value; } T& operator[](size_t index) { if (index >= size_) { throw std::out_of_range("Index out of bounds"); } return data_[index]; } size_t size() const { return size_; } size_t capacity() const { return capacity_; } }; Реальный пример: логгер событий Вот практическое применение динамического массива: struct LogEntry { std::string timestamp; std::string message; std::string severity; LogEntry(std::string ts, std::string msg, std::string sev) : timestamp(std::move(ts)), message(std::move(msg)), severity(std::move(sev)) {} }; class EventLogger { private: DynamicArray<LogEntry> logs; public: void log(const std::string& message, const std::string& severity) { auto now = std::chrono::system_clock::now(); auto time = std::chrono::system_clock::to_time_t(now); std::string timestamp = std::ctime(&time); timestamp.pop_back(); // Удаляется символ новой строки logs.push_back(LogEntry(timestamp, message, severity)); } void dump_logs() const { for (size_t i = 0; i < logs.size(); ++i) { std::cout << logs[i].timestamp << " [" << logs[i].severity << "] " << logs[i].message << "\n"; } } }; Добавление важного функционала Расширим функционал динамического массива: template<typename T> class DynamicArray { // ... предыдущий код ... public: // Конструктор копирования DynamicArray(const DynamicArray& other) : data_(new T[other.capacity_]), size_(other.size_), capacity_(other.capacity_) { for (size_t i = 0; i < size_; ++i) { data_[i] = other.data_[i]; } } // Конструктор перемещения DynamicArray(DynamicArray&& other) noexcept : data_(other.data_), size_(other.size_), capacity_(other.capacity_) { other.data_ = nullptr; other.size_ = other.capacity_ = 0; } // Оператор присваивания DynamicArray& operator=(const DynamicArray& other) { if (this != &other) { delete[] data_; data_ = new T[other.capacity_]; size_ = other.size_; capacity_ = other.capacity_; for (size_t i = 0; i < size_; ++i) { data_[i] = other.data_[i]; } } return *this; } void pop_back() { if (size_ > 0) { --size_; } } void clear() { size_ = 0; } bool empty() const { return size_ == 0; } T& front() { if (empty()) { throw std::out_of_range("Array is empty"); } return data_[0]; } T& back() { if (empty()) { throw std::out_of_range("Array is empty"); } return data_[size_ - 1]; } }; Динамические массивы в очереди задач Вот практический пример использования динамических массивов в системе планирования задач: class Task { public: std::function<void()> function; int priority; std::string name; Task(std::function<void()> f, int p, std::string n) : function(std::move(f)), priority(p), name(std::move(n)) {} }; class TaskQueue { private: DynamicArray<Task> tasks; public: void add_task(std::function<void()> func, int priority, const std::string& name) { tasks.push_back(Task(std::move(func), priority, name)); // Выполняется сортировка по приоритету в порядке убывания for (size_t i = tasks.size() - 1; i > 0; --i) { if (tasks[i].priority > tasks[i-1].priority) { std::swap(tasks[i], tasks[i-1]); } else { break; } } } void execute_all() { while (!tasks.empty()) { tasks.front().function(); tasks.pop_back(); } } void show_queue() const { for (size_t i = 0; i < tasks.size(); ++i) { std::cout << "Task: " << tasks[i].name << " (Priority: " << tasks[i].priority << ")\n"; } } }; Управление памятью и производительность Вот как оптимизируется производительность динамического массива: template<typename T> class DynamicArray { // ... предыдущий код ... public: void reserve(size_t new_capacity) { if (new_capacity > capacity_) { resize(new_capacity); } } void shrink_to_fit() { if (capacity_ > size_) { resize(size_); } } // Эффективная вставка в любой позиции void insert(size_t index, const T& value) { if (index > size_) { throw std::out_of_range("Invalid insertion index"); } if (size_ == capacity_) { resize(capacity_ * 2); } for (size_t i = size_; i > index; --i) { data_[i] = std::move(data_[i-1]); } data_[index] = value; ++size_; } // Эффективное удаление в любой позиции void erase(size_t index) { if (index >= size_) { throw std::out_of_range("Invalid erasure index"); } for (size_t i = index; i < size_ - 1; ++i) { data_[i] = std::move(data_[i+1]); } --size_; } }; Реальное применение: буфер обработки изображений Вот как динамические массивы используются при обработке изображений: struct Pixel { uint8_t r, g, b; Pixel(uint8_t r = 0, uint8_t g = 0, uint8_t b = 0) : r(r), g(g), b(b) {} }; class ImageBuffer { private: DynamicArray<Pixel> pixels; size_t width_; size_t height_; public: ImageBuffer(size_t width, size_t height) : width_(width), height_(height) { pixels.reserve(width * height); for (size_t i = 0; i < width * height; ++i) { pixels.push_back(Pixel()); } } void set_pixel(size_t x, size_t y, const Pixel& p) { if (x >= width_ || y >= height_) { throw std::out_of_range("Pixel coordinates out of bounds"); } pixels[y * width_ + x] = p; } Pixel& get_pixel(size_t x, size_t y) { if (x >= width_ || y >= height_) { throw std::out_of_range("Pixel coordinates out of bounds"); } return pixels[y * width_ + x]; } void apply_grayscale() { for (size_t i = 0; i < pixels.size(); ++i) { uint8_t gray = static_cast<uint8_t>( (pixels[i].r + pixels[i].g + pixels[i].b) / 3); pixels[i].r = pixels[i].g = pixels[i].b = gray; } } }; Этими реализациями демонстрируется, что динамические массивы  —  это основа многих реальных приложений. Не забывайте бережно относиться к памяти и при выборе между пользовательским динамическим массивом и std::vector учитывать конкретный сценарий. Хотя vector стандартной библиотеки хорошо протестирован и оптимизирован для большинства случаев, благодаря пониманию принципов работы динамических массивов принимаются более взвешенные решения относительно того, когда использовать каждый из вариантов. Читайте также: Как проходится ассоциативный массив на C++ C++: полное руководство по циклам while Механика разрешения имен и связывания на C++ Читайте нас в Telegram, VK и Дзен Перевод статьи ryan: Dynamic Arrays in C++: Comprehensive Guide
==============
Динамические массивы — это гибкое хранилище, которое автоматически увеличивается вместе с данными. Они создаются и используются для хранения изменяемого количества элементов. В примере показано создание и использование динамического массива, а также его применение для логирования событий, где создается структура `LogEntry` и класс `EventLogger` для записи и отображения логов. Также представлены расширенные возможности динамического массива, такие как конструкторы копирования и перемещения, операторы присваивания, а также функции для вставки, удаления и управления памятью, что позволяет эффективно управлять очередью задач. В примере использования динамических массивов для обработки изображений, класс `ImageBuffer` демонстрирует эффективное хранение и манипулирование пикселями, включая операции, такие как изменение цвета на оттенки серого.