cpp_ready | Unsorted

Telegram-канал cpp_ready - C/C++ Ready | Программирование

-

Авторский канал по разработке на C и C++. Ресурсы, обучения, задачи, шпаргалки. Ежедневно информация пополняется! Автор: @energy_it

Subscribe to a channel

C/C++ Ready | Программирование

Безопасное извлечение значения из map: try_emplace вместо лишних проверок!

Когда нужно добавить значение в std::map, если ключа ещё нет, код часто превращается в проверку через find, а потом отдельную вставку. Работает, но получается многословно.

В C++17 для этого есть try_emplace. Он добавляет элемент только если такого ключа ещё нет.

Например:

#include <map>
#include <string>
#include <iostream>

std::map<std::string, int> counters;

counters.try_emplace("errors", 0);


Если ключа "errors" ещё не было, он появится со значением 0.

Если ключ уже есть, значение не будет перезаписано:
counters["errors"] = 5;

counters.try_emplace("errors", 0);

std::cout << counters["errors"] << '\n'; // 5


Это удобно, когда значение дорого создавать или когда важно не затереть уже существующие данные.

try_emplace также возвращает пару: итератор и флаг, была ли вставка выполнена.
auto [it, inserted] = counters.try_emplace("warnings", 0);

if (inserted) {
std::cout << "created\n";
} else {
std::cout << "already exists\n";
}


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

🔥 try_emplace помогает аккуратно добавлять элементы в map: только если ключа ещё нет.

📣 C++ Ready | #практика

Читать полностью…

C/C++ Ready | Программирование

👀 Хочешь понять криптографию не только на уровне терминов, а через код?

Нашёл статью, где автор разбирает два собственных блочных шифра на C++: ESCK-7 и Seal. Это интересный инженерный разбор того, как может быть устроено блочное шифрование.

В статье:

• структура блочного шифра и работа с 64-битными числами
• генерация ключа и преобразования через XOR, NOT и циклические сдвиги
• примеры функций шифрования, расшифровки и изменения ключа

🔊 Продолжай читать на habr!


📣 C++ Ready | #статья

Читать полностью…

C/C++ Ready | Программирование

📂 Принципы проектирования и архитектуры API!

Например, REST задаёт стандарт взаимодействия по HTTP, GraphQL — гибкую выборку данных, а gRPC — эффективную бинарную коммуникацию.

На схеме — основные области: основы (контракты, HTTP, stateless), паттерны (REST, RPC, WebSockets), безопасность (OAuth2, JWT, TLS), а также дизайн и эволюция API.

Сохрани, чтобы не потерять!

📣 C++ Ready | #ресурс

Читать полностью…

C/C++ Ready | Программирование

😎 Нашёл полезную статью на Хабре — отличный пример, как начать писать простую игру на C++ с помощью SFML!

В этой статье:
• Как создать окно SFML и настроить главный цикл с обработкой событий
• Реализация singleton-контроллера для управления движением по клавишам
• Подключение и отображение текстур в игровом цикле

🔊 Советую продолжить читать на Habr!


📣 C++ Ready | #статья

Читать полностью…

C/C++ Ready | Программирование

🧐 Ravesli — подробный курс по C++ с нуля!

Это структурированный обучающий сайт, где собрано более 200 уроков по C++, охватывающих как базовые, так и углублённые темы языка. Отдельное внимание уделено практике: на сайте есть задания, проекты и даже разборы создания игр, что позволяет применять знания в реальных задачах.

📌 Оставляю ссылочку: ravesli.com

📣 C++ Ready | #сайт

Читать полностью…

C/C++ Ready | Программирование

📂 Напоминалка по иерархии памяти и работе storage!

Например, регистры — это самый быстрый уровень памяти внутри CPU, кэш (L1/L2/L3) снижает latency за счёт локальности данных, RAM хранит рабочее состояние приложений, а SSD/HDD используются для персистентного хранения с существенно более высоким временем доступа.

На картинке — базовая иерархия памяти, взаимодействие CPU — cache — RAM — disk, а также упрощённая модель работы HDD и архитектура SSD.

Сохрани, чтобы не потерять!

📣 C++ Ready | #ресурс

Читать полностью…

C/C++ Ready | Программирование

🐱 Project-Based Learning — обучение через проекты!

Этот репозиторий собирает лучшие гайды, где вместо теории — реальные проекты, которые можно реализовать с нуля. Внутри есть десятки идей. В разделах по C++ и C# можно найти идеи разного уровня: работа с файлами, сетевое взаимодействие, графика, многопоточность и др. задачи.

Оставляю ссылочку: GitHub 📱


📣 C++ Ready | #репозиторий

Читать полностью…

C/C++ Ready | Программирование

📂 Напоминалка по HTTP-статусам!

Например, код 200 означает, что всё прошло успешно, а 404 сообщает, что страница не найдена.
Очень полезно держать под рукой, когда работаешь с API или отлаживаешь backend.

На картинке показаны самые часто используемые статусы от 100 до 599.

Сохрани, чтобы не забыть!

📣 C++ Ready | #ресурс

Читать полностью…

C/C++ Ready | Программирование

💅 Beautiful — нейросеть для создания презентаций!

Это AI-инструмент для быстрого создания профессиональных презентаций. Достаточно добавить текст и идеи, а нейросеть автоматически подбирает дизайн, выравнивает элементы и формирует слайды. Встроенные умные шаблоны помогают делать презентации аккуратными без ручной настройки — AI сам адаптирует макет при добавлении контента.

📌 Оставляю ссылочку: beautiful.ai

📣 C++ Ready | #ресурс

Читать полностью…

C/C++ Ready | Программирование

📂 Шпаргалка по вычислительным архитектурам!

Например, CPU хорошо справляется с логикой, ветвлениями и задачами с низкой задержкой. GPU — про массовый параллелизм: подходит для обработки больших массивов данных, графики и вычислений.

На картинке — наглядное сравнение архитектуры, модели вычислений и типичных сценариев применения для каждого типа процессоров.

Сохрани, чтобы не потерять!

📣 C++ Ready | #ресурс

Читать полностью…

C/C++ Ready | Программирование

😍 PVS-Studio Blog — технические статьи по коду и разработке!

Здесь публикуются подробные разборы ошибок, уязвимостей и практик разработки. Основной фокус на статический анализ кода и реальные кейсы из проектов, включая разборы популярных open-source решений. Блог активно покрывает C++ и C#: публикуются статьи по анализу, поиску багов, особенностям работы компиляторов и практике.

📌 Оставляю ссылочку: pvs-studio.ru

📣 C++ Ready | #сайт

Читать полностью…

C/C++ Ready | Программирование

Почему emplace_back() не всегда лучше push_back()?

Есть популярное заблуждение, что emplace_back() всегда быстрее. Но это не так.

push_back() добавляет в контейнер уже готовый объект.
emplace_back() конструирует объект прямо на месте из переданных аргументов.

Например:

v.emplace_back("world");


здесь строка создается сразу внутри vector, и это действительно удобно.

Но если объект у тебя уже есть:
std::string s = "hello";
v.push_back(s);


то замена на
v.emplace_back(s);


обычно не дает никакого особого выигрыша. По смыслу это почти то же самое.

emplace_back() полезен, когда ты передаешь аргументы конструктора.
push_back() — когда у тебя уже есть готовое значение.

🔥 emplace_back() — не универсально лучший вариант. Используй его там, где нужен именно in-place construction.

📣 C++ Ready | #совет

Читать полностью…

C/C++ Ready | Программирование

👍 Free Programming Books — библиотека ресурсов по программированию на различных языках!

Проект постоянно обновляется сообществом и уже включает тысячи книг, курсов и обучающих ресурсов на разных языках, включая русский . Всё удобно разбито по категориям, отдельные разделы посвящены C++, C#, поэтому можно быстро найти нужную тему и начать изучение. Отлично подходит как база для самообучения.

Оставляю ссылочку: GitHub 📱


📣 C++ Ready | #репозиторий

Читать полностью…

C/C++ Ready | Программирование

📂 Напоминалка по архитектуре систем!

Например, Load Balancing распределяет нагрузку между серверами, а Caching помогает ускорить ответы за счёт хранения данных в памяти.

На картинке — 12 основных концепций, которые должен понимать каждый разработчик.

Сохрани, чтобы не потерять!

📣 C++ Ready | #ресурс

Читать полностью…

C/C++ Ready | Программирование

😎 Fluent Cpp — сайт, который поможет писать код на C++ понятным, лаконичным и профессиональным!

Здесь вы найдёте глубокие статьи, практические советы и техники, помогающие лучше использовать возможности языка, улучшать читаемость кода и развивать архитектурное мышление.

📌 Оставляю ссылочку: fluentcpp.com

📣 C++ Ready | #сайт

Читать полностью…

C/C++ Ready | Программирование

🔥База платных курсов и книг по программированию на весь 2026 год!🔥

Канал новый, потому что слишком много людей ждут халявы.

Тут всё, что обычно стоит тысячи:
— Авторские курсы, которые не найти в открытом доступе
— Самые свежие книги для старта
— Всё, что нужно, чтобы за полгода вырасти от мидла до сеньора

➡️ Залетайте, пока есть доступ!

Читать полностью…

C/C++ Ready | Программирование

Почему lambda с [=] может работать не так, как ты ожидаешь?

Потому что [=] копирует только локальные переменные из текущей области видимости.
Но если внутри метода класса ты обращаешься к полям объекта, на самом деле захватывается не сам объект целиком, а указатель this.

В таком коде:


cpp id="r8n2fs"
pool.enqueue([=] {
process(data_);
});


может казаться, что data_ безопасно скопирован внутрь lambda. Но это не так.

Фактически lambda использует this, а значит обращается к полю исходного объекта.
Если к моменту выполнения задачи объект уже уничтожен, код получит висячий указатель и undefined behavior.

Из-за этого баг особенно неприятный:
внешне всё выглядит как “захват по значению”
код может долго работать нормально
• а потом упасть в асинхронном сценарии, где объект уже не живёт


Если нужен именно снимок данных на момент создания lambda, лучше захватывать его явно:

cpp id="x1kz7d"
auto data = data_;
pool.enqueue([data] {
process(data);
});


А если нужен сам объект, важно явно контролировать его lifetime.

🔥[=] внутри метода класса не копирует поля объекта автоматически. Чаще всего ты захватываешь this, а не данные.

📣 C++ Ready | #совет

Читать полностью…

C/C++ Ready | Программирование

👩‍💻 Рассмотрим std::bitset — быстрый и понятный способ работы с битами!

С его помощью можно удобно хранить и обрабатывать флаги, состояния и биты без возни с ручными масками и побитовыми операциями. Это особенно полезно в системном программировании, играх и embedded-разработке.

📣 C++ Ready | #шпора

Читать полностью…

C/C++ Ready | Программирование

Почему после push_back() нельзя слепо использовать старый итератор?

Потому что std::vector хранит элементы в непрерывной области памяти.
Если при добавлении нового элемента текущей capacity уже не хватает, вектор перевыделяет память и переносит элементы в новое место.

После этого все итераторы, ссылки и указатели на старые элементы становятся невалидными.

В таком коде:

std::vector<int> v = {1, 2, 3};

auto it = v.begin();
v.push_back(4);

std::cout << *it << "\n";


it мог указывать на элемент в старом буфере памяти.
Если во время push_back() произошел reallocation, разыменование it — это уже undefined behavior.

Из-за этого баг особенно неприятный: код может

* работать “нормально” на маленьких примерах,
* ломаться только на других данных,
* проявляться нестабильно и не сразу.

Если после изменения vector тебе снова нужен итератор, его лучше получить заново.
А если хочешь уменьшить шанс перевыделения памяти, можно заранее вызвать reserve().

🔥 У vector итераторы живут только до тех пор, пока контейнер не изменил свое хранилище.

📣 C++ Ready | #совет

Читать полностью…

C/C++ Ready | Программирование

Не копировать объект, а просто обменять: std::swap как базовый инструмент

Иногда нужно просто поменять значения двух переменных местами. Вручную это обычно делают через временную переменную, но в C++ для этого уже есть готовый и понятный инструмент — std::swap.

Простой пример:

int a = 10;
int b = 20;

std::swap(a, b);

std::cout << a << ' ' << b << '\n';


После вызова значения переменных меняются местами:
a == 20
b == 10

То же самое работает не только с числами, но и с контейнерами:
std::vector<int> x{1, 2, 3};
std::vector<int> y{4, 5};

std::swap(x, y);

std::cout << x.size() << ' ' << y.size() << '\n';


Такой обмен обычно дешевле и чище, чем ручное переприсваивание. А главное — сразу видно намерение: мы не “что-то присваиваем”, а именно меняем объекты местами.

🔥 std::swap делает код проще и выразительнее: обмен значений — одной строкой и без лишнего шума.

📣 C++ Ready | #практика

Читать полностью…

C/C++ Ready | Программирование

Почему push_back() во время обхода vector может привести к багу?

Потому что при добавлении нового элемента std::vector может перевыделить память. А после этого все итераторы, ссылки и указатели на его элементы становятся невалидными.

Проблема в том, что range-based for тоже опирается на итераторы. И если внутри цикла вызвать:

v.push_back(5);


контейнер может переехать в другую область памяти. Тогда цикл продолжит работу уже с невалидными итераторами, а это undefined behavior.

То есть внешне код выглядит безобидно, но в реальности может:

• работать “случайно нормально”
• пропускать элементы
• падать
• давать нестабильное поведение

Особенно неприятно, что такой баг может проявляться не всегда, а только при определенном размере контейнера.

🔥 У vector добавление элемента может инвалидировать итераторы. Менять контейнер во время его обхода нужно очень осторожно.

📣 C++ Ready | #совет

Читать полностью…

C/C++ Ready | Программирование

Разбираем безопасное побитовое преобразование типов!

Сейчас научимся преобразовывать данные одного типа в другой без неопределённого поведения — с помощью функции std::bit_cast.

Сначала подключим необходимые библиотеки из стандартной поставки:

#include <bit>      // std::bit_cast
#include <cstdint> // uint32_t
#include <iostream>
#include <iomanip> // std::hex, std::setw, std::setfill


Теперь создадим число с плавающей точкой и преобразуем его в uint32_t, чтобы увидеть его внутреннее битовое представление:
float value = 3.1415926f;
uint32_t raw = std::bit_cast<uint32_t>(value);

std::cout << "Биты числа: 0x"
<< std::hex << std::setw(8) << std::setfill('0') << raw << '\n';


Преобразуем обратно, чтобы убедиться, что значение не потеряно:
float restored = std::bit_cast<float>(raw);
std::cout << std::dec << "Восстановлено: " << restored << '\n';


Результат при запуске программы:
Биты числа: 0x40490fda  
Восстановлено: 3.14159


🔥 Таким образом ты можешь безопасно перепаковывать данные между типами одинакового размера — без UB, memcpy и хаков.

📣 C++ Ready | #практика

Читать полностью…

C/C++ Ready | Программирование

👩‍💻 Разберём циклы с диапазоном и auto — способ проходить по контейнеру без индексов и явных итераторов!

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

📣 C++ Ready | #шпора

Читать полностью…

C/C++ Ready | Программирование

Меньше .first и .second: разбираем pair и tuple по-человечески!

Когда работаешь с std::pair, std::tuple или элементами std::map, код быстро зарастает обращениями вроде .first, .second и std::get<0>(). Читать это неудобно, особенно если таких мест много.

В C++17 для этого есть structured bindings. Они позволяют сразу разложить объект на именованные переменные.

Например, так можно пройтись по std::map:

#include <iostream>
#include <map>
#include <string>

std::map<std::string, int> scores{
{"alice", 10},
{"bob", 20}
};

for (const auto& [name, score] : scores) {
std::cout << name << ": " << score << '\n';
}


Без structured bindings пришлось бы писать менее выразительно:
for (const auto& item : scores) {
std::cout << item.first << ": "
<< item.second << '\n';
}


То же самое работает и с std::pair:
std::pair p{"error", 500};

auto [text, code] = p;
std::cout << text << ' ' << code << '\n';


Код становится короче и понятнее: вместо технических .first и .second появляются нормальные имена переменных, которые сразу передают смысл.

🔥 Structured bindings делают код читаемее: меньше служебного шума, больше понятных имён.

📣 C++ Ready | #практика

Читать полностью…

C/C++ Ready | Программирование

Как shared_ptr может привести к утечке памяти?

Потому что подсчет ссылок не умеет сам разрывать циклы.

Если два объекта держат друг друга через std::shared_ptr, их счетчики ссылок никогда не станут равны нулю. Даже когда внешний код уже “отпустил” оба объекта, они продолжают владеть друг другом.

Например, в такой схеме:

struct A {
std::shared_ptr<B> b;
};

struct B {
std::shared_ptr<A> a;
};


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

Именно поэтому shared_ptr не гарантирует автоматическое освобождение памяти во всех случаях.

Чтобы разорвать цикл, одна из ссылок должна быть не владеющей:
struct B {
std::weak_ptr<A> a;
};


std::weak_ptr не увеличивает счетчик владения, поэтому цикл исчезает, и объекты могут быть корректно уничтожены.

🔥 shared_ptr считает владельцев, но не умеет сам разрывать циклы. Для этого нужен weak_ptr.

📣 C++ Ready | #совет

Читать полностью…

C/C++ Ready | Программирование

✍️ CyberForum — крупнейшее сообщество разработчиков с разделами по C++ и C#!

Форум, где можно обсуждать задачи, получать помощь и разбирать кейсы из разработки. Есть активные разделы по C++ и C#: обсуждение синтаксиса, разбор ошибок, советы по обучению и практическая помощь. Форум можно использовать как источник знаний, особенно когда требуется разобраться в конкретной задаче или посмотреть, как её решают другие разработчик.

📌 Оставляю ссылочку: cyberforum.ru

📣 C++ Ready | #сайт

Читать полностью…

C/C++ Ready | Программирование

📂 Напоминалка по системам хранения данных!

Например, CPU cache и RAM дают минимальную задержку и используются для быстрых вычислений, а cloud storage и базы данных — для долговременного хранения и масштабирования.

На картинке — основные типы storage, которые используются в современных системах: от памяти процессора до облачных решений.

Сохрани, чтобы не потерять!

📣 C++ Ready | #ресурс

Читать полностью…

C/C++ Ready | Программирование

Почему захват [this] в асинхронном коде опасен?

Многие воспринимают [this] как безопасный способ вызвать метод объекта позже. Но на самом деле лямбда сохраняет только указатель this. Она не продлевает время жизни объекта.

Если задача выполнится уже после уничтожения Session, лямбда попробует обратиться к несуществующему объекту. В лучшем случае это закончится падением, в худшем — редким и трудноуловимым UB.

Проблема в том, что код выглядит абсолютно нормально. Пока объект жив, все работает. Но как только lifetime объекта и lifetime задачи расходятся, появляется use-after-free.

Например, опасный сценарий выглядит так:

void run(ThreadPool& pool) {
Session s;
s.start(pool);
} // s уже уничтожен, а задача может выполниться позже


Еще хуже, когда внутри лямбды идет доступ к полям объекта:
class Session {
std::string buffer;

public:
void start(ThreadPool& pool) {
pool.post([this] {
std::cout << buffer << "\n"; // доступ к уже мертвому объекту
});
}
};


Если объект должен пережить асинхронный вызов, его временем жизни нужно управлять явно. Обычно для этого используют shared_ptr и weak_ptr.
class Session : public std::enable_shared_from_this<Session> {
public:
void start(ThreadPool& pool) {
auto weak = weak_from_this();
pool.post([weak] {
if (auto self = weak.lock()) {
self->flush();
}
});
}

void flush();
};


Такой код сначала проверяет, жив ли объект вообще, и только потом вызывает метод.

Иногда используют и более прямой вариант с shared_from_this(), когда задаче нужно гарантированно удерживать объект живым до конца выполнения:
void start(ThreadPool& pool) {
auto self = shared_from_this();
pool.post([self] {
self->flush();
});
}


🔥 Захват [this] не делает асинхронный код безопасным. Если время жизни объекта не контролируется, это прямой путь к use-after-free.

📣 C++ Ready | #совет

Читать полностью…

C/C++ Ready | Программирование

Убираем все пробелы из строки!

Сейчас научимся быстро удалять все пробельные символы (пробел, таб, перевод строки) из строки. Это пригодится при парсинге ввода, чтении конфигов или очистке текстовых данных.

Сначала подключим необходимые библиотеки из стандартной поставки:

#include <string>
#include <algorithm> // std::erase_if (C++20)
#include <cctype> // std::isspace


Допустим, у нас есть строка с лишними пробелами и табуляцией:
std::string raw = "  Hello\tWorld \n ";


Теперь удалим все пробельные символы с помощью одного вызова:
std::erase_if(raw, [](unsigned char c) {
return std::isspace(c);
});
std::cout << raw << '\n';


Результат при запуске программы:
HelloWorld


🔥 Таким образом ты можешь быстро очищать строки от пробелов — без циклов, копий и лишнего кода.

📣 C++ Ready | #практика

Читать полностью…

C/C++ Ready | Программирование

👩‍💻 Разберём unique_ptr — умный указатель для безопасного и автоматического управления ресурсами!

С ним можно легко создавать объекты на куче, работать с сырыми указателями без передачи владения, освобождать или менять ресурс, обмениваться им за константное время, а также получать доступ к данным через * и ->

📣 C++ Ready | #шпора

Читать полностью…
Subscribe to a channel