C++ geek
3.56K subscribers
251 photos
2 videos
16 links
Учим C/C++ на примерах
Download Telegram
Удаление указателя NULL

Удаление указателя NULL не приводит к каким-либо изменениям и ошибкам.

➡️ @cpp_geek
Проверяем, содержит ли строка только буквы в C++

Мы можем использовать регулярное выражение, чтобы проверить, содержит ли строка только буквы.
Начиная с C++11, мы можем использовать std::regex_match для сопоставления последовательности с регулярным выражением.

➡️ @cpp_geek
Токенизация строки

Токенизация строки означает разделение строки относительно некоторого разделителя (разделителей). Есть много способов этого добиться.

Рассмотрим пример с функцией strtok(). Она разбивает строку по указанным разделителям и должна быть вызвана в цикле, на каждой итерации возвращая следующую часть. В конце возвращает NULL

➡️ @cpp_geek
Сколько раз будет выполняться этот цикл?

Еще один вопрос с подвохом с IT-собеседований. Если бы вы сказали 300, а i был объявлен как int, вы были бы правы. Но поскольку i объявлен как unsigned char, правильный ответ – зацикливание (бесконечный цикл).

Объясняем. Выражение 2 * half_limit будет повышаться до int (на основе правил преобразования C++) и заимеет значение 300. Но так как i – это unsigned char, он пересматривается по 8-битному значению, которое после достижения 255 будет переполняться, поэтому вернется к 0, и цикл будет продолжаться вечно.

➡️ @cpp_geek
Алгоритм count_if

Алгоритм count_if выполняет подсчет количества выполнений условия в последовательности.

➡️ @cpp_geek
Макросы и функции

При первом знакомстве макросы могут показаться обычными вызовами функций. Конечно, у них немного странный синтаксис, но они «ведут себя» как обычные функции. Тогда в чём разница?

Макрос можно условно назвать функцией обработки и замены программного кода: после сборки программы макросы заменяются макроопределениями. На картинке показан код на Си.

➡️ @cpp_geek
Узнаем время работы программы на С++

Для того, чтобы найти время работы программы, нужно воспользоваться функцией clock(). Прототип функции clock() находится в заголовочном файле <ctime>, который нужно подключить.

Функция clock() возвращает значение времени в миллисекундах (1с = 1000млс). Причём отсчёт времени начинается с момента запуска программы.

➡️ @cpp_geek
Алгоритм adjacent_find

Ищет первую пару одинаковых соседних элементов в диапазоне, ограниченном итераторами [first, last). Если соседние дубликаты найдены, то алгоритм возвращает однонаправленный итератор, указывающий на первый элемент пары, в противном случае возвращается last.

➡️ @cpp_geek
Алгоритм rotate

Меняет местами элементы в диапазоне [first, last) таким образом, что элемент n_first становится первым в новом диапазоне, а n_first-1 — последним.

Параметры:
first, last - диапазон элементов для изменения их порядка.
n_first - элемент, который должен стать первым в новом диапазоне.

➡️ @cpp_geek
Вычисление количества цифр числа

Чтобы вычислить количество цифр в числе, вместо цикла мы можем эффективно использовать log.

В нашем примере мы получаем, что количество цифр числа 2468 равно 4.

➡️ @cpp_geek
forward_list::unique() в C++ STL

forward_list::unique() — это встроенная функция в C++ STL, которая удаляет все последовательные повторяющиеся элементы из forward_list. Для сравнения используется бинарный предикат.

➡️ @cpp_geek
Работа с файлами

Для того чтобы прочитать файл понадобится выполнить те же шаги, что и при записи в файл с небольшими изменениями:

1) создать объект класса ifstream и связать его с файлом, из которого будет производиться считывание;
2) прочитать файл;
3) закрыть файл.

➡️ @cpp_geek
vptr (Virtual Pointer)

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

В этом примере мы создали два класса: Base и Derived. Класс Derived наследуется от класса Base и переопределяет его виртуальную функцию func(). Затем мы создали объект класса Derived и присвоили его адрес указателю на базовый класс Base.

Затем вызываем функцию func() с помощью указателя на базовый класс. Здесь vptr смотрит на таблицу виртуальных функций, чтобы определить, какую функцию вызывать.

Результатом будет вывод "Derived", так как мы переопределили функцию в классе Derived.

➡️ @cpp_geek
Функция remove_if

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

Функция выполняет итерацию по каждому члену контейнера списка и удаляет все элементы, которые возвращают true для предиката.

➡️ @cpp_geek
std::sort

std::sort — это функция стандартной библиотеки для сортировки элементов в контейнерах, таких как вектор или список.
Чтобы использовать std::sort, нужно подключить заголовочный файл .

Метод принимает в качестве аргументов итераторы на начало и конец сортируемой последовательности и сортирует элементы в возрастающем порядке по умолчанию.

Для определения порядка сортировки можно указать свой компаратор.

➡️ @cpp_geek
Что дают разные модификаторы при наследовании?

Ответ:
Изменяют зону видимости членов базового класса.
При private наследовании protected и public члены становятся private. При protected наследовании public становится protected. А при public ничего не изменяется.

➡️ @cpp_geek
Какая разница между статической и динамической библиотеками?

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

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

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

➡️ @cpp_geek
Примеры C++ кода до и после Ranges

Объединяем все строки в данном диапазоне в одно значение.

➡️ @cpp_geek
Перед вами два примера кода для печати вектора. Есть ли преимущества использования одного или другого?

Пример 1:
c++
vector vec;
/* ... .. ... */
for (auto itr = vec.begin(); itr != vec.end(); itr++) {
itr->print();
}


Пример 2:
c++
vector vec;
/* ... .. ... */
for (auto itr = vec.begin(); itr != vec.end(); ++itr) {
itr->print();
}


Хотя оба кода будут генерировать одинаковые выходные данные, пример 2 является более производительным вариантом. Это связано с тем, что оператор после инкремента itr++ обходится дороже, чем оператор перед инкрементом ++itr.

Оператор пост-инкремента генерирует копию элемента, прежде чем приступить к увеличению элемента и возврату копии. Более того, большинство компиляторов автоматически оптимизируют пример 1, неявно преобразуя его в пример 2.

➡️ @cpp_geek
Лямбда-выражения

В C++ 11 появилась поддержка лямбда-выражений. Они напоминают анонимные функции в JavaScript, их можно сравнить с функциональными объектами без имён. Они захватывают переменные в различных областях видимости в зависимости от их описания, для которого используются компактные синтаксические конструкции. Кроме того, их можно назначать переменным.

Лямбда-выражения — весьма полезный инструмент для тех случаев, когда в коде нужно выполнить какую-нибудь небольшую операцию, но для этого не хочется писать отдельную функцию. Ещё один распространённый пример их использования — создание функций, используемых при сравнении значений.

➡️ @cpp_geek
Можно ли использовать ссылку при возвращении из функции? Это хорошо или плохо?

Нельзя:
• никогда нельзя возвращать ссылку на локальную переменную, созданную внутри функции, потому что она разрушится сразу после выхода из функции;
• нельзя возвращать ссылку на выделенную память, потому что её нельзя будет очистить.

Можно:
• когда возвращается константная ссылка на член класса;
• когда Вы пишете оператор <<, оператор = и оператор индексирования, они должны возвращать ссылку на объект.

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

➡️ @cpp_geek