❓ Как получить размер файла в байтах?
В C++17 была добавлена библиотека filesystem, которая упрощает работу с файловой системой
❗️Стоит учитывать, что если файл был открыт не только вами, то размер может быть изменён извне
В C++17 была добавлена библиотека filesystem, которая упрощает работу с файловой системой
#include <filesystem>
int main()
{
std::uintmax_t size = std::filesystem::file_size("file.txt");
}
❗️Стоит учитывать, что если файл был открыт не только вами, то размер может быть изменён извне
🔥7
🍔 Отладочные макросы
Отладочные макросы в C++ используются для упрощения процесса отладки и диагностики программного кода
Основные отладочные макросы включают assert, static_assert и пользовательские макросы
🍓 assert
Макрос assert определён в заголовочном файле <cassert> и используется для проверки логических выражений во время выполнения программы. Если выражение вернёт false, assert завершает выполнение программы и выводит сообщение об ошибке
🍒 static_assert
static_assert введён в C++11 и позволяет проверять условия на этапе компиляции. Это особенно полезно для проверки условий, которые должны выполняться всегда, независимо от состояния программы во время выполнения
❗️Начиная с C++11 и C23 static_assert является ключевым словом
🫐 Пользовательские отладочные макросы
Вы также можете определять собственные макросы для отладки, которые помогут вам выводить дополнительную информацию или выполнять специфические проверки
Отладочные макросы в C++ используются для упрощения процесса отладки и диагностики программного кода
Основные отладочные макросы включают assert, static_assert и пользовательские макросы
🍓 assert
Макрос assert определён в заголовочном файле <cassert> и используется для проверки логических выражений во время выполнения программы. Если выражение вернёт false, assert завершает выполнение программы и выводит сообщение об ошибке
#include <cassert>
void test(int x) {
assert(x > 0 && "x must be positive");
// остальной код функции
}
int main() {
test(5); // проходит проверку
test(-3); // приводит к ошибке во время выполнения
return 0;
}
🍒 static_assert
static_assert введён в C++11 и позволяет проверять условия на этапе компиляции. Это особенно полезно для проверки условий, которые должны выполняться всегда, независимо от состояния программы во время выполнения
#include <type_traits>
template <typename T>
void check() {
static_assert(std::is_integral<T>::value, "T must be an integral type");
}
int main() {
check<int>(); // проходит проверку
check<float>(); // ошибка компиляции: T must be an integral type
return 0;
}
❗️Начиная с C++11 и C23 static_assert является ключевым словом
🫐 Пользовательские отладочные макросы
Вы также можете определять собственные макросы для отладки, которые помогут вам выводить дополнительную информацию или выполнять специфические проверки
#include <iostream>
#define DEBUG
#ifdef DEBUG
#define DEBUG_PRINT(x) std::cout << x << std::endl
#else
#define DEBUG_PRINT(x)
#endif
int main() {
int value = 42;
DEBUG_PRINT("Value: " << value);
return 0;
}
👍5🔥1
🍯 Задача с собеседования
Входные данные:
- Дан массив состоящий из int'ов
- Повторяющихся элементов в списке нет
Задача:
- Нужно преобразовать этот массив в строку, сворачивая соседние по числовому ряду числа в диапазоны
Примеры:
[1,4,5,2,3,9,8,11,0] => "0-5,8-9,11"
[1,4,3,2] => "1-4"
[1,4] => "1,4"
Входные данные:
- Дан массив состоящий из int'ов
- Повторяющихся элементов в списке нет
Задача:
- Нужно преобразовать этот массив в строку, сворачивая соседние по числовому ряду числа в диапазоны
Примеры:
[1,4,5,2,3,9,8,11,0] => "0-5,8-9,11"
[1,4,3,2] => "1-4"
[1,4] => "1,4"
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
std::string convertToRanges(std::vector<int>& nums) {
if (nums.empty()) {
return "";
}
// Сортируем вектор
std::sort(nums.begin(), nums.end());
std::vector<std::string> ranges;
int start = nums[0];
int prev = start;
for (size_t i = 1; i < nums.size(); ++i) {
if (nums[i] != prev + 1) {
// Если последовательность прервалась, добавляем диапазон
if (start == prev) {
ranges.push_back(std::to_string(start));
}
else {
ranges.push_back(std::to_string(start) + "-" + std::to_string(prev));
}
start = nums[i];
}
prev = nums[i];
}
// Добавляем последний диапазон
if (start == prev) {
ranges.push_back(std::to_string(start));
}
else {
ranges.push_back(std::to_string(start) + "-" + std::to_string(prev));
}
// Объединяем диапазоны в одну строку
std::ostringstream result;
for (size_t i = 0; i < ranges.size(); ++i) {
if (i > 0) {
result << ",";
}
result << ranges[i];
}
return result.str();
}
int main() {
std::vector<int> nums1 = { 1, 4, 5, 2, 3, 9, 8, 11, 0 };
std::cout << convertToRanges(nums1) << std::endl; // Ожидаемый вывод: "0-5,8-9,11"
std::vector<int> nums2 = { 1, 4, 3, 2 };
std::cout << convertToRanges(nums2) << std::endl; // Ожидаемый вывод: "1-4"
std::vector<int> nums3 = { 1, 4 };
std::cout << convertToRanges(nums3) << std::endl; // Ожидаемый вывод: "1,4"
return 0;
}
👍2
Почему использование std::endl может быть менее эффективным, чем \n в некоторых случаях?
Всё дело в буферизации вывода
- std::endl не только добавляет символ новой строки (\n) в поток, но и явно сбрасывает (flushes) буфер вывода. Это означает, что данные из буфера немедленно отправляются в устройство вывода (например, на экран или в файл).
- \n, напротив, просто добавляет символ новой строки в поток без принудительного сброса буфера. Буферизация остаётся управляемой самой стандартной библиотекой, и данные выводятся только тогда, когда буфер заполняется или программа явно вызывает std::flush.
В результате выполния кода будет заметно, что время вывода с \n будет меньше.
- std::endl не только добавляет символ новой строки (\n) в поток, но и явно сбрасывает (flushes) буфер вывода. Это означает, что данные из буфера немедленно отправляются в устройство вывода (например, на экран или в файл).
- \n, напротив, просто добавляет символ новой строки в поток без принудительного сброса буфера. Буферизация остаётся управляемой самой стандартной библиотекой, и данные выводятся только тогда, когда буфер заполняется или программа явно вызывает std::flush.
#include <iostream>
#include <chrono>
int main() {
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < 10000; ++i) {
std::cout << "Hello, World!" << std::endl; // Принудительный сброс после каждой строки
}
auto middle = std::chrono::high_resolution_clock::now();
for (int i = 0; i < 10000; ++i) {
std::cout << "Hello, World!\n"; // Буферизация, меньше операций I/O
}
auto end = std::chrono::high_resolution_clock::now();
std::cout << "Time with std::endl: "
<< std::chrono::duration_cast<std::chrono::milliseconds>(middle - start).count()
<< " ms\n";
std::cout << "Time with \\n: "
<< std::chrono::duration_cast<std::chrono::milliseconds>(end - middle).count()
<< " ms\n";
return 0;
}
В результате выполния кода будет заметно, что время вывода с \n будет меньше.
👍4
📚 Загадочная библиотека setjmp.h — неочевидный инструмент для управления потоком выполнения
Библиотека setjmp.h предоставляет два необычных макроса:
• setjmp — сохраняет текущее состояние программы (регистры, стек) в буфер jmp_buf
• longjmp — «откатывает» выполнение к сохранённому состоянию, как прыжок во времени
⚠️ Осторожно!
• Не заменяет исключения — нет вызова деструкторов (как в C++)
• Опасность утечек — если между setjmp и longjmp выделялась память, она не освободится
• Портит стек — может сломать логику функций
🛠 Где может пригодиться?
• Обработка критических ошибок (а-ля «аварийный выход»)
• Код для встраиваемых систем, где нужно быстро восстановить состояние
• Нестандартные хаки (но лучше так не делать 😈)
Библиотека C/C++ разработчика
Библиотека setjmp.h предоставляет два необычных макроса:
• setjmp — сохраняет текущее состояние программы (регистры, стек) в буфер jmp_buf
• longjmp — «откатывает» выполнение к сохранённому состоянию, как прыжок во времени
#include <stdio.h>
#include <setjmp.h>
jmp_buf jump_buffer;
void risky_function() {
printf("Готовимся к прыжку...\n");
longjmp(jump_buffer, 42); // Прыжок обратно в setjmp!
}
int main() {
int ret = setjmp(jump_buffer);
if (ret == 0) {
printf("Первая инициализация...\n");
risky_function();
} else {
printf("Вернулись с кодом: %d\n", ret); // Выведет 42!
}
return 0;
}
⚠️ Осторожно!
• Не заменяет исключения — нет вызова деструкторов (как в C++)
• Опасность утечек — если между setjmp и longjmp выделялась память, она не освободится
• Портит стек — может сломать логику функций
🛠 Где может пригодиться?
• Обработка критических ошибок (а-ля «аварийный выход»)
• Код для встраиваемых систем, где нужно быстро восстановить состояние
• Нестандартные хаки (но лучше так не делать 😈)
Библиотека C/C++ разработчика
👍3🥱3
Forwarded from Библиотека задач по C++ | тесты, код, задания
Какое утверждение о модулях C++20 является верным?
Anonymous Quiz
21%
Модули полностью заменяют заголовочные файлы и #include
56%
Модули компилируются быстрее заголовочных файлов и не подвержены проблемам One Definition Rule
5%
Модули могут экспортировать только классы, но не функции
14%
Модули автоматически решают все проблемы циклических зависимостей
4%
Модули работают только с компилятором GCC
#include <iostream>
#include <thread>
#include <chrono>
struct Counter {
long long a;
long long b;
};
void increment(long long& val) {
for (int i = 0; i < 100'000'000; i++) val++;
}
int main() {
Counter cnt{ 0, 0 };
auto start = std::chrono::high_resolution_clock::now();
std::thread t1(increment, std::ref(cnt.a));
std::thread t2(increment, std::ref(cnt.b));
t1.join(); t2.join();
auto end = std::chrono::high_resolution_clock::now();
std::cout << "Time: " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms\n";
return 0;
}
📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#междусобойчик
Please open Telegram to view this post
VIEW IN TELEGRAM
😁4🔥1🌚1
Стандарт C++ гарантирует, что можно зарегистрировать минимум N функций через
std::atexit. Найди баг в этом коде:#include <cstdlib>
#include <iostream>
void dummy_handler() {
static int counter = 0;
std::cout << "Handler " << ++counter << "\n";
}
int main() {
// Регистрируем 100 обработчиков
for (int i = 0; i < 100; ++i) {
if (std::atexit(dummy_handler) != 0) {
std::cerr << "Failed at " << i << "\n";
return 1;
}
}
std::cout << "All registered!\n";
return 0;
}
📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#междусобойчик
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Библиотека задач по C++ | тесты, код, задания
🧩 Выходной челлендж: дочисти парсер команд
У тебя есть заготовка интерактивной оболочки — read-eval-print loop. Осталось дописать несколько ключевых частей.
Задача: заполни три TODO.
💬 Покажи своё решение — особенно интересны варианты с std::istringstream и ручным разбором.
📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#междусобойчик
У тебя есть заготовка интерактивной оболочки — read-eval-print loop. Осталось дописать несколько ключевых частей.
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
std::vector<std::string> parseCommand(const std::string& line) {
// TODO: разбить строку на токены по пробелам
// Учти: несколько пробелов подряд — не ошибка
}
void execute(const std::vector<std::string>& tokens) {
if (tokens.empty()) return;
if (tokens[0] == "echo") {
// TODO: вывести все аргументы через пробел
} else if (tokens[0] == "exit") {
exit(0);
} else {
// TODO: вывести "Unknown command: <имя команды>"
}
}
int main() {
std::string line;
while (true) {
std::cout << "> ";
if (!std::getline(std::cin, line)) break;
execute(parseCommand(line));
}
}
Задача: заполни три TODO.
💬 Покажи своё решение — особенно интересны варианты с std::istringstream и ручным разбором.
📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#междусобойчик
Что такое линкер (linker) в процессе сборки C++ программы?
Anonymous Quiz
3%
Инструмент, преобразующий исходный код в объектный файл
91%
Инструмент, объединяющий объектные файлы в исполняемый файл
5%
Инструмент, обрабатывающий директивы #include
1%
Инструмент, оптимизирующий байт-код программы
1%
Инструмент, проверяющий синтаксис исходного кода
😁2🤔1
Forwarded from Библиотека задач по C++ | тесты, код, задания
🔥 Найди баг: копирование строки сломало указатель
‼️ Задача: найди баг (если он есть), объясни, почему он связан с SSO, и предложи исправление.
📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#междусобойчик
#include <string>
#include <iostream>
struct Token {
std::string value;
const char* ptr;
Token(const std::string& s) : value(s), ptr(value.data()) {}
};
int main() {
Token t1("hi");
Token t2 = t1; // копируем
std::cout << t1.ptr << "\n"; // "hi"
std::cout << t2.ptr << "\n"; // ???
}
📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#междусобойчик
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Библиотека C/C++ разработчика | cpp, boost, qt
#include <ranges>
#include <vector>
void process(const auto& view) {
for (auto x : view) { (void)x; }
}
int main() {
std::vector<int> data = { 1, 2, 3, 4, 5 };
auto pred = [](int x) {
return x % 2 == 0;
};
auto filtered = data | std::views::filter(pred);
process(filtered); // ❌ не компилируется
}
Объясни механизм: почему
begin() const невозможен в принципе, а не по недосмотру комитета.📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#междусобойчик
Please open Telegram to view this post
VIEW IN TELEGRAM
❤🔥182💯169❤150🔥150🥰148
Forwarded from Библиотека задач по C++ | тесты, код, задания
🏆 Задача на выходные: string_view vs string в API
Перед тобой два варианта API логгера. Выбери лучший и обоснуй. Нет единственно верного ответа — важна аргументация.
✏️ Напиши в комментариях: какой метод в каком варианте правильный, а какой — нет. Предложи «идеальный»
📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#константная_правильность
Перед тобой два варианта API логгера. Выбери лучший и обоснуй. Нет единственно верного ответа — важна аргументация.
#include <string>
#include <string_view>
// Вариант А
class LoggerA {
public:
void log(const std::string& msg);
void setPrefix(const std::string& prefix);
std::string getLastMessage() const;
};
// Вариант Б
class LoggerB {
public:
void log(std::string_view msg);
void setPrefix(std::string_view prefix);
std::string_view getLastMessage() const;
};
// Контекст использования:
// 1. log() вызывается тысячи раз в секунду
// 2. setPrefix() — один раз при старте
// 3. getLastMessage() — для диагностики
// 4. Логгер хранит последнее сообщение внутри
LoggerC.📍Навигация: Вакансии • Задачи • Собесы
Библиотека C/C++ разработчика
#константная_правильность
Please open Telegram to view this post
VIEW IN TELEGRAM