-
Авторский канал по разработке на C и C++. Ресурсы, обучения, задачи, шпаргалки. Ежедневно информация пополняется! Автор: @energy_it
👩💻 Осваиваем корутины — пишем асинхронный код просто и понятно!
Корутины — это функции, выполнение которых можно приостанавливать и продолжать. Они позволяют писать асинхронный и ленивый код без громоздких колбэков и сложного состояния.
Что важно знать:
• Три ключевых оператора: co_await, co_yield, co_return.
• Можно создавать генераторы, которые возвращают значения по одному.
• Асинхронные функции выглядят как обычные — без вложенности и запутанных цепочек вызовов.
Парсим числа из строки на чистом C++!
Иногда нужно разобрать строку с данными. Например числа из конфига, координаты, значения из файла или простую команду пользователя.
Есть строка:
std::string text = "10 20 30 40";
#include <iostream>
#include <sstream>
#include <string>
std::istringstream input(text);
int value;
while (input >> value) {
std::cout << value << '\n';
}
10
20
30
40
std::string point = "15 42";
std::istringstream input(point);
int x;
int y;
input >> x >> y;
if (!(input >> value)) {
std::cout << "Invalid number\n";
}
Почему std::vector::reserve может ускорить добавление элементов?
std::vector хранит элементы в непрерывном участке памяти.
Когда ты добавляешь новые элементы через push_back, вектор может понять, что места больше нет. Тогда ему приходится выделить новый участок памяти, перенести туда старые элементы и только потом добавить новый.
В маленьком примере это почти незаметно:
std::vector<int> numbers;
for (int i = 0; i < 100; ++i) {
numbers.push_back(i);
}
std::vector<int> numbers;
numbers.reserve(100);
for (int i = 0; i < 100; ++i) {
numbers.push_back(i);
}
std::vector<int> v;
v.reserve(100);
std::cout << v.size() << '\n'; // 0
std::cout << v.capacity() << '\n'; // 100
v.resize(100);
👩💻 Числовые вычисления проще, чем кажется!Стандартная библиотека C++ предоставляет удобные функции для работы с числами: можно легко суммировать значения, считать скалярное произведение, генерировать последовательности или выполнять накопительные вычисления.
📣 C++ Ready | #шпора
Проверяем, что строка — целиком число (без “42abc → 42”)
Сейчас научимся превращать строку в int так, чтобы не принимать мусор вроде "42abc". Это будет полезно для CLI, конфигов и пользовательского ввода.
Допустим, пришла строка с хвостом:
std::string raw = "42abc";
std::stoi может распарсить только начало и вернуть 42. Поэтому берём pos — позицию, где парсинг остановился:size_t pos = 0;
int value = std::stoi(raw, &pos);
pos не дошёл до конца строки — значит в конце есть лишние символы:if (pos != raw.size()) {
std::cout << "Некорректный ввод: лишние символы\n";
}try-catch:try {
size_t pos = 0;
int value = std::stoi(raw, &pos); if (pos != raw.size()) { std::cout << "Лишние символы\n"; return 0; }
std::cout << "Число: " << value << '\n';} catch (const std::invalid_argument&) {
std::cout << "Некорректный ввод: не число\n";
} catch (const std::out_of_range&) {
std::cout << "Число вне диапазона int\n";
}"42abc"):Лишние символы
📂 Concurrency и parallelism - это не одно и то же!
Concurrency - это про структуру программы: несколько задач могут продвигаться вперёд в перекрывающиеся промежутки времени. Parallelism - это уже физическое одновременное выполнение, например на нескольких ядрах CPU.
На картинке — визуальное отличие concurrent execution от parallel execution. Сохрани, чтобы не потерять!
📣 C++ Ready | #ресурс
😍 learn-cpp - это бесплатный интерактивный туториал по, который позволяет учиться прямо в браузере!
На сайте ты найдёшь короткие уроки и практические упражнения с мгновенной проверкой: от Hello, World, переменных и функций до тем вроде указателей, массивов, linked lists и базового OOP.
📌 Оставляю ссылочку: learn-cpp.org
📣 C++ Ready | #ресурс
📂 Напоминалка по std::string в C++!
Например, .find() помогает быстро найти подстроку, .substr() — вырезать часть строки, а .replace() — заменить текст без лишней ручной работы.
На картинке — полезные методы std::string, работа с итераторами, конвертация строк в числа и обратно, а также базовые операции изменения строк.
Сохрани, чтобы не потерять!
📣 C++ Ready | #ресурс
📂 Шпаргалка по библиотеке {fmt}!
Например, fmt::print и fmt::format позволяют писать безопасное, читаемое и производительное форматирование без printf и перегруженных stringstream.
На изображении собраны возможности {fmt}: плейсхолдеры и именованные аргументы; форматирование целых и вещественных чисел; работа со строками, диапазонами и кортежами.
Сохрани, чтобы не потерять!
📣 C++ Ready | #ресурс
Генерируем случайный пароль на чистом C++!
Иногда нужно быстро создать случайную строку: временный пароль, токен для тестов или случайный идентификатор. Вручную выбирать символы неудобно, поэтому можно собрать маленький генератор с помощью стандартной библиотеки.
Для этого используем std::random_device, std::mt19937 и std::uniform_int_distribution.
Теперь создадим функцию, которая генерирует пароль нужной длины:
std::string make_password(std::size_t length) {
const std::string chars =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789"
"!@#$%^&*";
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<std::size_t> dist(
0, chars.size() - 1
);
std::string result;
for (std::size_t i = 0; i < length; ++i) {
result += chars[dist(gen)];
}
return result;
}main:int main() {
std::string password = make_password(12);
std::cout << "Password: " << password << '\n';
}Password: a7K!pQ2z#Lm9
std::random в деле и сразу получить полезный результат.
Почему std::accumulate может неожиданно обрезать дроби?
На первый взгляд здесь всё нормально:
std::vector<double> v = {1.5, 2.5, 3.5};
auto sum = std::accumulate(v.begin(), v.end(), 0);auto sum = std::accumulate(v.begin(), v.end(), 0.0);
Почему std::endl может тормозить программу?
Многие используют std::endl как обычный перевод строки:
std::cout << i << std::endl;
std::endl делает две вещи.for (int i = 0; i < 100000; ++i) {
std::cout << i << std::endl;
}std::cout << i << '\n';
std::endl стоит использовать тогда, когда flush действительно нужен.
Быстро удаляем пробелы в начале и в конце строки!
Когда мы читаем строки из файла, пользовательского ввода или сетевого запроса — часто получаем "шум": пробелы, табы, переводы строк.
Во многих языках есть встроенные trim()-функции, но в C++ стандартной такой нет. Зато её легко реализовать самому — компактно, эффективно и без сторонних зависимостей.
Начнём с подключения нужных заголовков:
#include <string>
#include <cctype> // std::isspace
#include <algorithm>
#include <iostream>
trim, которая:std::string trim(const std::string& s) {
auto start = std::find_if_not(s.begin(), s.end(), ::isspace);
auto end = std::find_if_not(s.rbegin(), s.rend(), ::isspace).base();
return (start < end) ? std::string(start, end) : "";
}std::string raw = " \t\n Hello, world! \n ";
std::string cleaned = trim(raw);
std::cout << "[" << cleaned << "]\n";
[Hello, world!]
Почему std::move внутри forwarding-функции может быть ошибкой?
Потому что T&& в шаблоне — это не всегда rvalue-ссылка.
В таком контексте это forwarding reference, которая может принять и временный объект, и обычную lvalue-переменную.
Например:
std::string s = "hello";
wrapper(s);
wrapper передается lvalue.process(std::move(value));
value в rvalue.process() может переместить данные из объекта s, хотя вызывающий код передавал обычную переменную и не ожидал, что из нее что-то “заберут”.std::move, а в том, что он всегда делает аргумент кандидатом на перемещение.template <class T>
void wrapper(T&& value) {
process(std::forward<T>(value));
}
std::forward<T> сохраняет исходную категорию значения:std::move всегда говорит: “можно перемещать”.std::move часто слишком агрессивен. Если хочешь сохранить поведение аргумента — используй std::forward<T>.
👩💻 Рассмотрим std::tie - удобный способ распаковывать значения и сравнивать объекты!С его помощью можно связывать переменные в tuple из ссылок, пропускать ненужные значения через std::ignore и компактно сравнивать несколько полей сразу.
📣 C++ Ready | #шпора
В России можно посещать IT-мероприятия хоть каждый день: как оффлайн, так и онлайн
Но где их находить? Как узнавать о них раньше, чем когда все начнут выкладывать фотографии оттуда?
Переходите на канал IT-Мероприятия России. В нём каждый день анонсируются мероприятия со всех городов России
📆 в канале размещаются как онлайн, так и оффлайн мероприятия;
👩💻 можно найти ивенты по любому стеку: программирование, frontend-backend разработка, кибербезопасность, дата-аналитика, osint, devops и другие;
🎙 разнообразные форматы мероприятий: митапы с коллегами по цеху, конференции и вебинары с известными опытными специалистами, форумы и олимпиады от важных представителей индустрии и многое другое
А чтобы не искать по разным форумам и чатам новости о предстоящих ивентах:
🚀 IT-мероприятия России — подписывайся и будь в курсе всех предстоящих мероприятий!
Напоминалка по выбору контейнера в C++!
Например, std::vector обычно подходит, когда нужен быстрый доступ по индексу и хранение элементов подряд в памяти, а std::deque удобен, если нужно эффективно добавлять элементы и в начало, и в конец.
На картинке краткая схема выбора sequence-контейнера: std::vector, std::deque, std::list, std::forward_list и std::array.
Сохрани, чтобы не потерять!
📣 C++ Ready | #ресурс
📂 Напоминалка по числовым типам в C++!
Например, std::numeric_limits<T>::max() позволяет узнать максимальное значение типа, а std::numeric_limits<T>::lowest() — минимальное возможное значение.
На картинке — краткая шпаргалка по целочисленным типам (int, long, uint64_t и другим), числам с плавающей точкой (float, double, long double) и возможностям std::numeric_limits.
Сохрани, чтобы не потерять!
📣 C++ Ready | #ресурс
😍 Whimsical — AI-инструмент для создания схем, mind map и документации!
Сервис для визуализации идей, архитектуры и рабочих процессов. В Whimsical можно создавать mind map, заметки и диаграммы, а встроенный AI помогает автоматически генерировать схемы и структурировать информацию по текстовому запросу. Удобно продумывать архитектуру проектов.
📌 Оставляю ссылочку: whimsical.com
📣 C++ Ready | #сайт
📂 Напоминалка по бинарному поиску и алгоритмам ranges в C++20!
Например, ranges::binary_search помогает быстро проверить наличие элемента в отсортированном диапазоне, а ranges::lower_bound и ranges::upper_bound — находить границы вставки или диапазон одинаковых значений.
На картинке — алгоритмы бинарного поиска из std::ranges, которые стоит держать под рукой при работе с контейнерами и алгоритмами STL.
Сохрани, чтобы не потерять!
📣 C++ Ready | #ресурс
👩💻 std::exchange: забрать старое значение за одну строку!
Иногда нужно заменить значение, но при этом не потерять то, что было раньше. std::exchange как раз делает это без лишнего кода: возвращает старое значение и сразу записывает новое.
Что важно знать:
• Удобен, когда нужно обновить состояние и сохранить предыдущее
• Хорошо подходит для флагов, reset-логики и простых state-переходов
• Делает намерение понятнее, чем ручное “сохранили старое, потом присвоили новое”
<utility>, которая часто помогает убрать пару лишних строк и сделать код аккуратнее.
RAII для ресурсов: FILE* без утечек и fclose в каждом return
Классика в C/C++ — открыть файл и не забыть закрыть:
FILE* f = std::fopen(path, "rb");
if (!f) return;
do_work(f);
if (something_bad()) {
std::fclose(f); // легко забыть
return;
}
std::fclose(f);
return, исключениях или новых ветках кода fclose легко потерять — и получить утечку ресурса.FILE* в std::unique_ptr с кастомным deleter’ом:using FilePtr = std::unique_ptr<FILE, decltype(&std::fclose)>;
FilePtr f(std::fopen(path, "rb"), &std::fclose);
if (!f) return;
do_work(f.get());
if (something_bad()) {
return; // fclose вызовется сам
}
FilePtr open_file(const char* path, const char* mode) {
return FilePtr(std::fopen(path, mode), &std::fclose);
}
auto f = open_file(path, "rb");
if (!f) return;close/fclose/free — ресурс закрывается гарантированно при любом выходе из функции, а код становится короче и надёжнее.
Почему для класса часто нужен virtual destructor?
Если у класса есть virtual-функции, его часто используют полиморфно:
Base* task = new Task;
delete task;
struct Base {
virtual void run() = 0;
};struct Base {
virtual ~Base() = default;
virtual void run() = 0;
};
☕️ C++ Tutorial — подробный гайд по C++ для начинающих!
Здесь пошагово разбираются основы языка: переменные, циклы, функции, массивы, указатели, ООП, классы и другие важные темы. Всё объясняется простым языком с примерами кода и постепенным усложнением материала. Помимо основ, есть статьи по более продвинутым возможностям языка и практические примеры.
📌 Оставляю ссылочку: beginnersbook.com
📣 C++ Ready | #сайт
😎 Как рендер может тормозить UI?
В этой статье:• Как разделить CPU и GPU задачи
• Как работают очереди и command buffers
• Зачем Vulkan требует явной синхронизации
🔊 Продолжай читать на habr!
📂 Напоминалка по netcat (nc) — универсальному сетевому «швейцарскому ножу»
Лёгкая утилита-«швейцарский нож» для TCP/UDP и UNIX-сокетов: слушает/устанавливает соединения, пересылает файлы, делает обратные оболочки, стримит и сканирует порты/граббинг баннеров.
Часто комбинируют с openssl, tar, dd для шифрования, архивации и клонирования.
📣 C++ Ready | #ресурс
☕️ C++ Basics Tutorials — структурированное изучение C++ с практикой!
Внутри собраны базовые темы языка: переменные, циклы, функции, указатели, ООП, STL и другие важные вещи, которые нужны для понимания современного C++. Материал подан максимально понятно и с примерами кода, поэтому можно сразу запускать и разбирать, как всё работает на практике.
Оставляю ссылочку: GitHub 📱
📂 Паттерны многопоточности, которые стоит знать!
Многопоточность — это не запуск нескольких thread. В реальных системах приходится управлять shared state, очередями задач, producer/consumer-потоками, read/write доступом и координацией выполнения.
На картинке — популярные multithreading patterns: read-write lock, thread pool, producer-consumer, future/promise и другие подходы, которые помогают организовать concurrent-код.
Сохрани, чтобы не потерять!
📣 C++ Ready | #ресурс
💡 Автор показывает, как на чистом C++ собрать минимальный трассировщик лучей и получить первый рендер без тяжёлых движков!
В этой статье:• как устроена базовая камера и выпуск лучей в сцену
• как найти пересечение луча со сферой и рассчитать цвет пикселя
• как добавить материалы, отражения, тени и получить объёмную картинку
🔊 Продолжай читать на habr!
📂 Напоминалка по масштабированию базы данных!
Например, Indexing ускоряет поиск по таблицам, а Sharding помогает разделить большие объёмы данных между несколькими узлами.
На картинке — 7 стратегий масштабирования БД: индексы, materialized views, denormalization, vertical scaling, caching, replication и sharding.
Сохрани, чтобы не потерять!
📣 C++ Ready | #ресурс