Senior C++ Developer
12.9K subscribers
1.29K photos
3 videos
581 links
№ 4931128893
Изучаем C++.

По вопросам сотрудничества: @adv_and_pr
Download Telegram
Функции Бесселя

Функции Бесселя в С++ представляют собой набор математических функций, которые используются для решения различных задач, связанных с волновой оптикой, акустикой, механикой и другими областями физики и инженерии. Они названы в честь немецкого математика Фридриха Бесселя.

В С++ функции Бесселя можно использовать, включив заголовочный файл <cmath>. Стандартная библиотека С++ предоставляет следующие функции Бесселя:

j0, j1, jn: Эти функции вычисляют функции Бесселя первого рода Jn(x) для заданных значениях x и целых индексов n.
y0, y1, yn: Эти функции вычисляют функции Бесселя второго рода (также известные как функции Неймана) Yn(x) для заданных значений x и целых индексов n.
I0, I1, In: Эти функции вычисляют модифицированные функции Бесселя первого рода In(x) для заданных значений x и целых индексов n.
K0, K1, Kn: Эти функции вычисляют модифицированные функции Бесселя второго рода Kn(x) для заданных значений x и целых индексов n.

#для_продвинутых
sync_file_range()

Вызов sync_file_range() позволяет точно контролировать синхронизацию открытого файла, задаваемого файловым дескриптором fd, с диском.

В offset задаётся начальный байт диапазона файла, который нужно синхронизировать. В nbytes указывается длина синхронизируемого диапазона (в байтах); если nbytes равно нулю, то синхронизируются все байты, начиная с offset и до конца файла. Синхронизация выполняется в единицах размера системной страницы: значение offset округляется к меньшей границе страницы; (offset+nbytes-1) округляется к большей границе страницы.

Данный системный вызов очень опасен и не должен использоваться в переносимых программах. Ни одна из этих операций перезаписи не касается метаданных файла. Поэтому, если приложение строго не выполняет перезаписи уже выделенных дисковых блоков, то нет никаких гарантий, что данные будут будьте доступны после катастрофического отказа.

#для_продвинутых
equal_range

Функция equal_range используется для нахождения диапазона элементов в упорядоченном контейнере, которые имеют определенное значение. Она возвращает пару итераторов, представляющих начало и конец диапазона, в котором находятся элементы с указанным значением. Это полезно, когда вы хотите найти все элементы с определенным значением в упорядоченном контейнере, таком как std::set или std::map.

Прототип функции equal_range выглядит следующим образом:

std::pair<iterator, iterator> equal_range(const Key& key);

Где:
iterator — тип итератора контейнера.
Key — значение, для которого нужно найти диапазон.

#для_продвинутых
SFML

SFML (Simple and Fast Multimedia Library) — это библиотека, предназначенная для разработки мультимедийных приложений, включая 2D и 3D игры, аудио и видео. Она предоставляет доступ к различным мультимедийным ресурсам и упрощает работу с графикой, аудио, сетью и вводом.

Вот основные шаги для использования SFML в C++:

1. Сначала установите библиотеку SFML на вашем компьютере. Вы можете скачать библиотеку с официального сайта SFML и следовать инструкциям по установке для вашей операционной системы.
2. Создайте новый проект C++ в вашей среде разработки (например, Visual Studio, Code::Blocks, CLion и др.).
3. Вам нужно убедиться, что ваш проект настроен для использования SFML. Для этого укажите пути к заголовочным файлам и библиотекам SFML в настройках проекта.
4. Ваш код будет включать заголовочные файлы SFML и вызов функций для работы с графикой, аудио и другими мультимедийными ресурсами.
5. Скомпилируйте свой проект с учетом настроек SFML, и запустите его.

#для_продвинутых
Специализация шаблонов

Специализация шаблонов (template specialization) позволяет предоставить особое определение (или реализацию) шаблона для конкретного типа данных или набора типов данных. Это позволяет адаптировать поведение шаблона для специфических сценариев, когда общее определение шаблона не подходит.

Специализации шаблонов позволяют создавать более точную и оптимизированную логику для определенных типов данных или сценариев использования. При компиляции компилятор выбирает наиболее подходящую специализацию на основе переданных типов или аргументов шаблона.

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

#для_продвинутых
Boost.Serialization

Boost.Serialization — это часть библиотеки Boost, которая позволяет сериализовать и десериализовать объекты C++ для передачи их между разными программами или для сохранения их состояния в файле.

Напоминаем: Сериализация — это процесс преобразования объектов C++ в последовательность байтов, которые могут быть записаны в файл или переданы через сеть. Десериализация — это процесс обратного преобразования последовательности байтов обратно в объекты C++.

#для_продвинутых
Метапрограммирование шаблонов

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

Важно помнить, что метапрограммирование шаблонов может быть сложным и приводить к сложноотлавливаемым ошибкам компиляции. Эта техника часто используется в библиотеках стандартной библиотеки C++, таких как STL (Standard Template Library), для создания обобщенных и эффективных алгоритмов и контейнеров.

#для_продвинутых
Деструктор

Деструктор (destructor) — это специальный метод класса, который вызывается при уничтожении объекта этого класса. Деструктор используется для освобождения ресурсов, которые были выделены объекту во время его жизни. Например, деструктор может закрывать файлы, освобождать динамически выделенную память или выполнять другие действия, необходимые для корректной очистки ресурсов.

Деструктор в C++ имеет тот же имя, что и класс, но с символом тильды (~) перед именем. Например, если у вас есть класс с именем MyClass, то деструктор этого класса будет называться ~MyClass.

#для_начинающих
std::memory_order_acquire

std::memory_order_acquire — это один из флагов (memory order) в стандартной библиотеке C++, который используется в контексте многопоточности и атомарных операций. Он указывает, что операция должна выполняться с учетом уровня доступа к памяти, который предписывает, что все чтения, выполняемые перед этой операцией, должны быть завершены до того, как она начнется. Это означает, что все изменения, сделанные в памяти другими потоками, должны быть видимы для текущей операции.

std::memory_order_acquire применяется обычно к операциям чтения (например, чтение значения из разделяемой переменной), чтобы гарантировать корректное чтение данных из разделяемой памяти в многопоточной среде. В сочетании с std::memory_order_release, этот флаг может использоваться для создания атомарных операций с соблюдением необходимых гарантий согласованности памяти в многопоточной среде.

#для_продвинутых
Минимальный и максимальный элементы

Функции std::min_element и std::max_element возвращают минимальный и максимальный элементы соответственно из диапазона. В качестве коллекции элементов может выступать контейнер или массив. Диапазон элементов задается начальным и конечным итераторами контейнера/массива.

Здесь находим мин и макс элементы вектора numbers. В обоих случаях в качестве диапазона выступает весь контейнер — от итератора begin(numbers) до итератора end(numbers). Результатом каждой функции также является итератор. Потому для получения значения (максимального/минимального значения) применяем операцию разыменования: *std::min_element(...).

Так как диапазон поиска значений может быть только частью контейнера, ограниченной итераторами, то мы можем найти макс/мин значения на каком-то определенном диапазоне:

std::cout << "Min: " << *std::min_element(begin(numbers), end(numbers)) << std::endl;
std::cout << "Max: " << *std::max_element(begin(numbers), end(numbers)) << std::endl;

#для_продвинутых
Проклятые Земли. Изменяем движок игры! Подробности + ПРИМЕР реверсинга движка

Смотреть статью
Рекурсивный мьютекс

Рекурсивный мьютекс (recursive mutex) — это специальный тип мьютекса, который позволяет одному и тому же потоку многократно захватывать мьютекс, не приводя к блокировке. Это полезно в ситуациях, когда один и тот же поток может вызывать функции, которые используют мьютекс, несколько раз вложено, и без рекурсивных мьютексов это могло бы привести к блокировке потока.

В C++ стандартная библиотека предоставляет класс std::recursive_mutex для работы с рекурсивными мьютексами. Код с примера создает два потока, каждый из которых вызывает функцию foo, которая захватывает рекурсивный мьютекс несколько раз. Благодаря рекурсивному мьютексу, это не вызывает блокировки, и программа корректно работает.

Обратите внимание, что необходимо быть осторожным при использовании рекурсивных мьютексов, чтобы избежать возможных проблем с блокировкой и дедлоками.

#для_продвинутых
insert_or_assign

insert_or_assign является методом контейнера std::map и std::unordered_map (и их многих других вариантов), который был добавлен в стандарт C++17. Этот метод вставляет новый элемент или обновляет существующий элемент с указанным ключом.

#для_начинающих
std::make_pair

std::make_pair — это шаблонная функция в стандартной библиотеке C++, предназначенная для создания объекта std::pair. std::pair — это структура, предназначенная для хранения пары значений (двух элементов) различных типов данных.

Пример на картинке создает пару значений (a и b) с использованием std::make_pair и выводит их на экран. Функция make_pair автоматически определяет типы элементов и возвращает объект std::pair с этими значениями.

#для_начинающих
Функция memmove

Функция memmove в C++ используется для перемещения блока памяти из одной части массива в другую, даже если эти блоки памяти перекрываются. Это отличается от функции memcpy, которая не гарантирует правильное копирование, если исходный и целевой блоки перекрываются.

Прототип функции memmove выглядит следующим образом:

void* memmove(void* destination, const void* source, size_t num);


Здесь:

destination — указатель на начало блока памяти, в который нужно переместить данные.
source — указатель на начало блока памяти, из которого нужно скопировать данные.
num — количество байтов, которые нужно переместить.

Функция memmove обеспечивает корректное копирование данных, даже если destination и source перекрываются. Это означает, что она может быть использована в случаях, когда memcpy может привести к неправильным результатам из-за перекрытия.

#для_продвинутых
Функция floor

Функция floor в C++ используется для округления числа с плавающей запятой (типа float или double) вниз до ближайшего целого числа, которое меньше или равно исходному числу. Функция floor является частью стандартной библиотеки C++ и объявлена в заголовочном файле <cmath>.

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

#для_начинающих
CUDA

CUDA (Compute Unified Device Architecture) — это платформа для параллельных вычислений, разработанная NVIDIA, которая позволяет использовать графические процессоры (GPU) для ускорения вычислений. CUDA позволяет программистам писать код на C++ для выполнения на GPU. Вот основные шаги по использованию CUDA в C++:

1. Установите необходимое программное обеспечение.
— Установите драйверы CUDA для вашей видеокарты с официального сайта NVIDIA.
— Установите среду разработки, такую как NVIDIA CUDA Toolkit, которая включает в себя компилятор NVCC и другие инструменты для разработки на CUDA.

2. Напишите CUDA-ядро.
— Создайте функцию на C++, которая будет выполняться на GPU. Эта функция обычно называется «ядром».
— Пометьте функцию ключевым словом __global__, чтобы указать, что она будет выполняться на GPU.

#для_продвинутых
Сырые указатели

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

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

#для_продвинутых
Барьеры памяти

Барьеры памяти (memory barriers) используются для управления порядком доступа к памяти в многозадачных и многопоточных программах. Барьеры памяти помогают гарантировать, что операции чтения и записи выполняются в правильной последовательности, чтобы избежать гонок данных и неопределенного поведения.

В C++ барьеры памяти можно устанавливать с использованием стандартных библиотечных средств, таких как атомарные операции и мьютексы, а также с использованием модификаторов памяти, таких как volatile и std::memory_order

#для_начинающих
try_emplace

try_emplace
— это одна из функций в стандартной библиотеке C++, введенная в стандарте C++17. Она используется для вставки элементов в контейнеры, такие как std::map, std::unordered_map, std::set, и std::unordered_set, с оптимизированным процессом вставки.

Сигнатура try_emplace выглядит следующим образом:

template<class... Args>
std::pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);


Она принимает ключ k и набор аргументов Args, которые используются для создания значения, которое будет ассоциировано с этим ключом. Функция возвращает пару, где первый элемент — итератор к вставленному или уже существующему элементу, а второй элемент — флаг, указывающий, был ли элемент вставлен (true) или уже существовал (false).

Преимущество try_emplace заключается в том, что она позволяет оптимизировать вставку в контейнеры, так как она не создает промежуточный объект, если элемент с заданным ключом уже существует. Вместо этого она создает значение внутри контейнера, если ключ отсутствует, и возвращает итератор к созданному или существующему элементу.

#для_продвинутых