TGViewer
Channel Public Channel
Уютное сообщество С++ разработчиков

Уютное сообщество С++ разработчиков

@cppturbo

Изучаем C++.
Ресурсы, обучения, задачи, шпаргалки.
Вопросы с собеседований по C++ и ответы на них.
Задачи и тесты по C++ для тренировки и обучения.
По рекламе: @anothertechrock
Subscribers
776
Photos
82
Videos
8
Links
83

Showing posts older than #268 · Back to latest

Older Posts 16 shown
Post #263 273
А вам когда-нибудь снился С++ в кошмарах?)
  • 👍 1
Post #262 306
Книги по C++.
Скачивайте и читайте.

Beginning C++ Compilers
Автор: Ademi B. Ospanova

Modern C++ for Absolute Beginners
Автор: Slobodan Dmitrović

C++20: Get the Details
Автор: Grimm Rainer

Starting Out with C++ from Control Structures to Objects
Автор: Tony Gaddis

Software Architecture with C++
Автор: Adrian Ostrowski

Expert C++
Автор: Araks Tigranyan

Современный C++ безопасное использование
Автор: Джон Лакос

Методы программирования в задачах и примерах на C/C++
Автор: А. А. Корнев

Программирование на языке C++. Практический курс
Автор: Огнева М.

Самоучитель "Уроки по C++"
Автор: Ravesli

#cpp #подборка
Post #261 253
📚 Основное определение:
Поинтеры — это переменные, которые хранят адреса других переменных в памяти. Они активно используются в системном программировании, разработке встраиваемых систем и при работе с динамической памятью. Главная особенность — прямой доступ к памяти и эффективная работа с данными.

🔍 Ключевые концепции:

1️⃣ Объявление поинтера: int *ptr — создает указатель на целое число
2️⃣ Получение адреса: &variable — оператор для получения адреса переменной
3️⃣ Разыменование: *ptr — доступ к значению по адресу в указателе
4️⃣ Арифметика указателей: ptr++ перемещает указатель на следующий элемент
5️⃣ Связь с массивами: array[i] эквивалентно *(array + i)
6️⃣ Динамическая память: malloc() и free() для управления памятью

💻 Практический пример:

int array[] = {1, 2, 3, 4, 5}; 
int *ptr = array;

for(int i = 0; i < 5; i++) {
printf(«%d «, *ptr); ptr++;
}
// Вывод: 1 2 3 4 5


📎 Дополнительные ресурсы:

👉 Полное руководство по указателям в C
  • ❤ 1
  • 👍 1
  • 👏 1
Post #260 239
🎲 Тест «Тест по C++»
Пройдите тестирование, проверьте свои знания с помощью онлайн тест-викторины C++, подготовьтесь к экзаменам по C++.
🖊 15 вопросов · ⏱ 30 сек
  • 👍 1
  • 🥱 1
Post #259 260
Считаем единички
#задачки

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

Вроде бы простая и популярная задача: посчитать количество единиц в битовом представлении числа. Уверен, что большинство из вас решали эту задачу.

Однако популярный подход - не самый эффективный, элегантный и интересный.

Благо существует множество непопулярных, но очень интересных решений! О них я расскажу в завтра в ответном посте.

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

А чтобы умудренным опытом людям было немного интереснее, давайте ограничим условия. Задачу надо решить либо за константное время(в среднем), либо за наименьшее количество строчек. Выражения вне цикла for разделенные символом ; считаются разными строчками.

int count_ones(unsigned num) {
// Here your code
}


Challenge yourself. Stay cool.
  • ❤ 1
Post #258 229
А как вы пришли к программированию на плюсах?
Как это изменило вашу жизнь?
  • 😁 3
Post #257 270
Сортировка массива на C++ за 30 секунд!
  • 👍 5
  • 👌 1
Post #252 245
👩‍💻 Вспоминаем методы для контейнеров!

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

Уютное сообщество С++ разработчиков | #шпора
  • 🔥 3
  • ❤ 1
Post #250 217
Потокобезопасный интерфейс
#новичкам

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

Возьмем максимально простую реализацию самой простой очереди:

struct Queue {
void push(int value) {
storage.push_back(value);
}
void pop() {
storage.pop_front();
}
bool empty() {
return storage.empty();
}
int& front() {
return storage.front();
}
private:
std::deque<int> storage;
};


Она конечно потокоНЕбезопасная. То есть ей можно адекватно пользоваться только в рамках одного потока.

Как может выглядеть код простого консьюмера этой очереди?

while(condition)
if (!queue.empty()) {
auto & elem = queue.front();
process_elem(elem);
queue.pop();
}


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

Бабахаем везде лок гард на один мьютекс и дело в шляпе!

struct Queue {
void push(int value) {
std::lock_guard lg{m};
storage.push_back(value);
}
void pop() {
std::lock_guard lg{m};
storage.pop_front();
}
bool empty() {
std::lock_guard lg{m};
return storage.empty();
}
int& front() {
std::lock_guard lg{m};
return storage.front();
}
private:
std::deque<int> storage;
std::mutex m;
};


Все доступы к очереди защищены. Но спасло ли реально это нас?

Вернемся к коду консюмера:

while(true)
if (!queue.empty()) {
auto & elem = queue.front();
process_elem(elem);
queue.pop();
}



А вдруг у нас появится еще один консюмер? Тогда в первом из них мы можем войти условие, а в это время второй достанет последний элемент. Получается, что мы получим доступ к неинициализированной памяти в методе front.

То есть по факту в многопоточном приложении полученный стейт сущности сразу же утрачивает свою актуальность.

Что делать? Не только сами методы класса должны быть потокобезопасными. Но еще и комбинации использования этих методов тоже должны обладать таким свойством. И с данным интерфейсом это сделать просто невозможно.

Если стейт утрачивает актуальность, то мы вообще не должны давать возможность приложению получать стейт очереди. Нам нужны только команды управления. То есть push и pop.

struct ThreadSafeQueue {
void push(int value) {
std::lock_guard lg{m};
storage.push_back(value);
}
std::optional<int> pop() {
std::lock_guard lg{m};
if (!storage.empty()) {
int elem = storage.front();
storage.pop_front();
return elem;
}
return nullopt;
}
private:
std::deque<int> storage;
std::mutex m;
};


Внутри метода pop мы можем использовать проверять и получать стейт очереди, так как мы оградились локом. Возвращаем из него std::optional, который будет хранить фронтальный элемент, если очередь была непуста. В обратном случае он будет пуст.

Теперь консюмер выглядит так:

while(true) {
auto elem = queue.pop();
if (elem)
process_elem(elem.value());
}


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

Stay safe. Stay cool.

#concurrency #design #goodpractice
  • ❤ 1
Post #249 674
➕ Игра на C++ в консоли ➕
  • 😁 2
  • ❤ 1
  • 👌 1
Post #248 1.1K
А как вы пришли к программированию на плюсах?
Как это изменило вашу жизнь?
  • 👍 3
  • 😁 2
  • 👌 1
Post #246 2.25K
Что выведет следующий код и почему?

#include <iostream>

void foo(int a) { std::cout << "int"; }
void foo(char a) { std::cout << "char"; }

int main() {
foo(97);
return 0;
}


Ответ:
int

Почему?
Число 97 по умолчанию имеет тип
int, поэтому вызывается версия foo(int).
Если бы мы передали
'a' (символьный литерал), то вызвалась бы foo(char).

⚡️ Подвох: Если бы параметр был
unsigned char, то могла бы произойти неявная конверсия, но тут всё однозначно! 😊
  • 👍 6
  • 👌 4
Post #245 2.25K
Современный C++ безопасное использование

Авторы: Джон Лакос, Витторио Ромео,
Ростислав Хлебников
Дата выхода: 2023

#cpp #ru

Скачать книгу
  • 👍 2
Older posts →
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →