Горячее
Лучшее
Свежее
Подписки
Сообщества
Блоги
Эксперты
Войти
Забыли пароль?
или продолжите с
Создать аккаунт
Я хочу получать рассылки с лучшими постами за неделю
или
Восстановление пароля
Восстановление пароля
Получить код в Telegram
Войти с Яндекс ID Войти через VK ID
Создавая аккаунт, я соглашаюсь с правилами Пикабу и даю согласие на обработку персональных данных.
ПромокодыРаботаКурсыРекламаИгрыПополнение Steam
Пикабу Игры +1000 бесплатных онлайн игр
“Рецепт Счастья” — увлекательная игра в жанре «соедини предметы»! Помогите Эмили раскрыть тайны пропавшего родственника, найти сокровища и восстановить её любимое кафе.

Рецепт Счастья

Казуальные, Головоломки, Новеллы

Играть

Топ прошлой недели

  • AlexKud AlexKud 38 постов
  • SergeyKorsun SergeyKorsun 12 постов
  • SupportHuaport SupportHuaport 5 постов
Посмотреть весь топ

Лучшие посты недели

Рассылка Пикабу: отправляем самые рейтинговые материалы за 7 дней 🔥

Нажимая кнопку «Подписаться на рассылку», я соглашаюсь с Правилами Пикабу и даю согласие на обработку персональных данных.

Спасибо, что подписались!
Пожалуйста, проверьте почту 😊

Помощь Кодекс Пикабу Команда Пикабу Моб. приложение
Правила соцсети О рекомендациях О компании
Промокоды Биг Гик Промокоды Lamoda Промокоды МВидео Промокоды Яндекс Директ Промокоды Отелло Промокоды Aroma Butik Промокоды Яндекс Путешествия Постила Футбол сегодня

C++ + Программирование

С этим тегом используют

IT IT юмор Программист Python Помощь Картинка с текстом Разработка Юмор Все
510 постов сначала свежее
3
mcnikirikitiki
4 месяца назад
Лига программистов

Основы программирования на C++: функции, шаблоны⁠⁠

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

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

Здравствуйте, мои маленькие любители программирования!

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

Основные концепции функций

  1. Что такое функция? Функция — это блок кода, который выполняет определенную задачу. Она может принимать входные данные (аргументы), обрабатывать их и возвращать результат. В языке C++ каждая программа начинается с выполнения функции main(), которая является точкой входа в программу.

    int main() {

    // Код программы

    return 0;

    }

    • int перед main() указывает, что функция возвращает целое число.

    • return 0; означает успешное завершение программы.

  2. Создание простой функции

    Рассмотрим пример функции, которая складывает два числа:

    int Sum(int a, int b) {

    return a + b;

    }

    • int перед именем функции указывает, что функция возвращает значение типа int.

    • Sum — это имя функции.

    • (int a, int b) — это параметры функции, то есть значения, которые передаются в функцию при её вызове.

    Пример использования функции Sum:

    int main() {

    int x = 17, y = 42;

    int z = Sum(x, y); // Вызов функции Sum

    std::cout << "Сумма: " << z << "\n"; // Выведет 59

    }

  3. Функции без возвращаемого значения

    Если функция не должна возвращать результат, её можно объявить как void. Это означает, что функция просто выполняет какие-то действия, но не возвращает никаких данных.

    void DoSomething(double d, char c) {

    std::cout << "Число: " << d << ", Символ: " << c << "\n";

    }

    Пример использования:

    int main() {

    DoSomething(3.14, '@'); // Выведет: Число: 3.14, Символ: @

    }

  4. Рекурсивные функции

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

    #include <cstdint> // Для uint64_t

    std::uint64_t Factorial(std::uint64_t n) {

    if (n == 0) {

    return 1; // Базовый случай

    }

    return n * Factorial(n - 1); // Рекурсивный вызов

    }

    Пример использования:

    int main() {

    std::cout << "Факториал 5: " << Factorial(5) << "\n"; // Выведет 120

    }

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


Аргументы функций

  1. Передача аргументов по значению

    По умолчанию аргументы передаются "по значению", то есть функция работает с копиями переменных. Любые изменения внутри функции не влияют на исходные переменные.

    void f(int x, int y) {

    x = 10; // Изменение x не повлияет на внешнюю переменную

    y = 20; // Изменение y не повлияет на внешнюю переменную

    }

    int main() {

    int a = 1, b = 2;

    f(a, b);

    std::cout << "a: " << a << ", b: " << b << "\n"; // Выведет: a: 1, b: 2

    }

  2. Передача аргументов по ссылке

    Чтобы изменять исходные переменные внутри функции, используются ссылки (&). Это позволяет функции работать с оригинальными переменными, а не с их копиями.

    void Swap(int& x, int& y) { // Передача по ссылке

    int temp = x;

    x = y;

    y = temp;

    }

    int main() {

    int a = 1, b = 2;

    Swap(a, b);

    std::cout << "a: " << a << ", b: " << b << "\n"; // Выведет: a: 2, b: 1

    }

  3. Константные ссылки

    Для сложных типов данных (например, векторов или строк) лучше передавать аргументы по константной ссылке (const &). Это позволяет избежать лишнего копирования данных и защищает их от случайного изменения внутри функции.

    void PrintVector(const std::vector<int>& vec) {

    for (int num : vec) {

    std::cout << num << " ";

    }

    std::cout << "\n";

    }

    int main() {

    std::vector<int> numbers = {1, 2, 3, 4, 5};

    PrintVector(numbers); // Выведет: 1 2 3 4 5

    }


Возвращаемые значения функций

  1. Возврат простых типов

    Функция может возвращать любые типы данных, такие как int, double, char и т.д. Например:

    double Divide(double a, double b) {

    return a / b;

    }

    int main() {

    double result = Divide(10.0, 2.0);

    std::cout << "Результат деления: " << result << "\n"; // Выведет: 5.0

    }

  2. Возврат сложных типов

    Возврат сложных типов данных (например, векторов или строк) также возможен. Компилятор автоматически оптимизирует процесс копирования таких объектов.

    std::string Concatenate(const std::vector<std::string>& parts) {

    std::string result;

    for (const auto& part : parts) {

    result += part;

    }

    return result;

    }

    int main() {

    std::vector<std::string> words = {"Hello", " ", "World", "!"};

    std::cout << Concatenate(words) << "\n"; // Выведет: Hello World!

    }

  3. Опасность возврата ссылок на локальные переменные

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

    int& GetLocalVariable() {

    int x = 10;

    return x; // Ошибка! x будет уничтожен после завершения функции

    }


Лямбда-функции

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

#include <algorithm>

#include <vector>

int main() {

std::vector<int> numbers = {5, 2, 8, 1, 9};

// Сортировка в обратном порядке с помощью лямбда-функции

std::sort(numbers.begin(), numbers.end(), [](int a, int b) {

return a > b; // Сравнение в обратном порядке

});

for (int num : numbers) {

std::cout << num << " "; // Выведет: 9 8 5 2 1

}

}


Шаблоны

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

  1. Шаблонные функции

    Шаблонная функция позволяет работать с разными типами данных без необходимости писать отдельные версии для каждого типа.

    template<typename T>

    T Max(T a, T b) {

    return (a > b) ? a : b;

    }

    int main() {

    std::cout << "Максимум: " << Max(10, 20) << "\n"; // Выведет: 20

    std::cout << "Максимум: " << Max(3.14, 2.71) << "\n"; // Выведет: 3.14

    std::cout << "Максимум: " << Max("apple", "banana") << "\n"; // Выведет: banana

    }

  2. Шаблонные структуры

    Шаблоны также можно использовать для создания универсальных структур данных. Например, структура Triple, которая хранит три значения разных типов:

    template<typename T1, typename T2, typename T3>

    struct Triple {

    T1 first;

    T2 second;

    T3 third;

    };

    int main() {

    Triple<int, double, std::string> data = {1, 3.14, "Hello"};

    std::cout << "First: " << data.first << ", Second: " << data.second

    << ", Third: " << data.third << "\n";

    }


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

Задачи на функции

1. Простые функции

  1. Функция "Приветствие"
    Напишите функцию void Greet(const std::string& name), которая выводит приветствие в формате:
    "Привет, [имя]!".
    Пример:

    Greet("Анна"); // Вывод: Привет, Анна!

  2. Вычисление площади прямоугольника
    Напишите функцию double CalculateRectangleArea(double width, double height), которая принимает ширину и высоту прямоугольника и возвращает его площадь.
    Пример:

    double area = CalculateRectangleArea(5.0, 3.0); // Результат: 15.0

  3. Проверка числа на четность
    Напишите функцию bool IsEven(int number), которая возвращает true, если число четное, и false — если нечетное.
    Пример:

    bool result = IsEven(4); // Результат: true


2. Функции с передачей по ссылке

  1. Увеличение значения на 1
    Напишите функцию void Increment(int& value), которая увеличивает переданное значение на 1.
    Пример:

    int x = 5;

    Increment(x);

    std::cout << x; // Вывод: 6

  2. Обмен значений двух переменных
    Реализуйте функцию void Swap(int& a, int& b), которая меняет значения двух переменных местами.
    Пример:

    int x = 10, y = 20;

    Swap(x, y);

    std::cout << x << " " << y; // Вывод: 20 10


3. Рекурсивные функции

  1. Числа Фибоначчи
    Напишите рекурсивную функцию int Fibonacci(int n), которая возвращает n-е число Фибоначчи.
    Пример:

    int result = Fibonacci(7); // Результат: 13

  2. Степень числа
    Напишите рекурсивную функцию int Power(int base, int exponent), которая возводит число base в степень exponent.
    Пример:

    int result = Power(2, 3); // Результат: 8


Задачи на шаблоны

4. Шаблонные функции

  1. Минимум двух чисел
    Напишите шаблонную функцию T Min(T a, T b), которая возвращает минимальное из двух значений.
    Пример:

    int result1 = Min(10, 20); // Результат: 10

    double result2 = Min(3.14, 2.71); // Результат: 2.71

  2. Сравнение строк
    Напишите шаблонную функцию bool AreEqual(T a, T b), которая возвращает true, если два значения равны, и false — если нет.
    Пример:

    bool result1 = AreEqual(5, 5); // Результат: true

    bool result2 = AreEqual("hello", "world"); // Результат: false

  3. Сумма элементов массива
    Напишите шаблонную функцию T SumArray(const std::vector<T>& arr), которая вычисляет сумму всех элементов вектора.
    Пример:

    std::vector<int> numbers = {1, 2, 3, 4};

    int result = SumArray(numbers); // Результат: 10


5. Шаблонные структуры

  1. Шаблонная структура "Точка"
    Создайте шаблонную структуру Point<T>, которая хранит координаты точки в двумерном пространстве. Добавьте метод void Print(), который выводит координаты точки.
    Пример:

    Point<int> p1 = {3, 4};

    p1.Print(); // Вывод: (3, 4)

  2. Шаблонная структура "Пара"
    Создайте шаблонную структуру Pair<T1, T2>, которая хранит два значения разных типов. Добавьте метод void Print(), который выводит значения пары.
    Пример:

    Pair<int, std::string> pair = {42, "Ответ"};

    pair.Print(); // Вывод: (42, Ответ)


Задачи на лямбда-функции

6. Лямбда-выражения

  1. Фильтрация чисел
    Используя лямбда-функцию, напишите программу, которая фильтрует числа из вектора, оставляя только четные.
    Пример:

    std::vector<int> numbers = {1, 2, 3, 4, 5, 6};

    std::vector<int> evenNumbers;

    std::copy_if(numbers.begin(), numbers.end(), std::back_inserter(evenNumbers), [](int x) {

    return x % 2 == 0;

    });

    // Результат: evenNumbers = {2, 4, 6}

  2. Сортировка строк по длине
    Используя лямбда-функцию, отсортируйте вектор строк по их длине.
    Пример:

    std::vector<std::string> words = {"apple", "banana", "kiwi"};

    std::sort(words.begin(), words.end(), [](const std::string& a, const std::string& b) {

    return a.size() < b.size();

    });

    // Результат: words = {"kiwi", "apple", "banana"}


Дополнительные задачи

7. Комбинированные задачи

  1. Калькулятор
    Напишите шаблонную функцию T Calculator(T a, T b, char operation), которая выполняет одну из операций (+, -, *, /) над двумя числами.
    Пример:

    int result = Calculator(10, 5, '+'); // Результат: 15

    double result2 = Calculator(10.0, 2.0, '/'); // Результат: 5.0

  2. Поиск максимального элемента в массиве
    Напишите шаблонную функцию T FindMax(const std::vector<T>& arr), которая возвращает максимальный элемент вектора.
    Пример:

    std::vector<int> numbers = {3, 1, 4, 1, 5, 9};

    int max = FindMax(numbers); // Результат: 9

  3. Подсчет слов в строке
    Напишите функцию int CountWords(const std::string& text), которая подсчитывает количество слов в строке. Слова разделены пробелами.
    Пример:

    int count = CountWords("Hello world!"); // Результат: 2


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

Показать полностью
[моё] Программирование Гайд IT C++ Windows Длиннопост
48
2
mcnikirikitiki
4 месяца назад
Лига программистов

Сборка проектов на C/C++: от базовых принципов к продвинутым решениям. Часть II - Инструменты автоматизации сборки⁠⁠

1. Почему важно правильно настраивать сборку?

Правильная настройка сборки — это не просто удобство для разработчиков, но и ключ к успешному развитию проекта. Вот несколько причин:

  • Масштабируемость: Чем больше проект, тем сложнее его поддерживать вручную. Автоматизация сборки позволяет легко добавлять новые файлы и зависимости.

  • Переносимость: Проекты часто запускаются на разных платформах (Linux, Windows, macOS). Хорошая система сборки гарантирует, что код будет работать везде.

  • Совместная работа: Когда в команде несколько разработчиков, автоматизированная сборка помогает избежать проблем с конфигурацией окружения.

  • CI/CD: Современные системы непрерывной интеграции и доставки (CI/CD) требуют четко настроенной сборки. Это ускоряет тестирование и деплой.


2. Универсальные Makefile'ы

В примере выше мы рассмотрели базовый Makefile. Теперь давайте сделаем его более универсальным, чтобы он мог обрабатывать любое количество исходных файлов:

# Имя исполняемого файла

TARGET = program

# Компилятор и флаги

CXX = g++

CXXFLAGS = -Wall -std=c++17

LDFLAGS =

# Список исходных файлов

SRCS = $(wildcard *.cpp)

OBJS = $(SRCS:.cpp=.o)

# Основная цель

all: $(TARGET)

# Как собирать программу

$(TARGET): $(OBJS)

$(CXX) $(OBJS) $(LDFLAGS) -o $(TARGET)

# Правило для объектных файлов

%.o: %.cpp

$(CXX) $(CXXFLAGS) -c $< -o $@

# Очистка

clean:

rm -f $(OBJS) $(TARGET)

Здесь используется функция wildcard, которая автоматически находит все .cpp файлы в директории. Это делает Makefile более гибким.


3. Работа с зависимостями

3.1. Установка библиотек через пакетный менеджер

Это самый простой способ, но он имеет ограничения:

  • Разные дистрибутивы Linux могут использовать разные пакетные менеджеры (apt, yum, pacman).

  • Версии библиотек в репозиториях могут быть устаревшими.

Пример установки libcurl:

sudo apt-get install libcurl4-openssl-dev

3.2. Локальная компиляция библиотек

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

wget https://curl.se/download/curl-8.11.1.tar.bz2

tar -jxf curl-8.11.1.tar.bz2

cd curl-8.11.1

./configure --with-openssl

make

Теперь используйте локальные пути при компиляции:

g++ curlexample.cpp -o curlexample \

-I ./curl-8.11.1/include \

-L ./curl-8.11.1/lib/.libs \

-l curl


4. Продвинутые инструменты сборки

4.1. CMake

CMake — это мощный инструмент, который поддерживает кроссплатформенную сборку. Вот пример CMakeLists.txt для проекта с зависимостью от libcurl:

cmake_minimum_required(VERSION 3.10)

project(CurlExample LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)

set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(CURL REQUIRED)

add_executable(CurlExample curlexample.cpp)

target_link_libraries(CurlExample PRIVATE CURL::libcurl)

Чтобы собрать проект:

mkdir build

cd build

cmake ..

make

4.2. Meson

Meson — это современный инструмент, который генерирует файлы для Ninja. Пример meson.build:

project('CurlExample', 'cpp')

# Поиск libcurl

dependency('libcurl')

executable('curlexample', 'curlexample.cpp', dependencies: ['libcurl'])

Сборка:

meson setup build

cd build

ninja

4.3. SCons

SCons использует Python для написания рецептов. Пример SConstruct:

env = Environment()

env.Append(LIBS=['curl'])

env.Program(target='curlexample', source='curlexample.cpp')

Сборка:

scons


5. Docker для изоляции сборки

Docker позволяет создавать изолированные контейнеры с нужной версией ОС и библиотек. Это особенно полезно для старых проектов или CI/CD.

Пример Dockerfile:

FROM ubuntu:20.04

RUN apt-get update && apt-get install -y \

build-essential cmake git libcurl4-openssl-dev

WORKDIR /app

COPY . .

RUN mkdir build && cd build && cmake .. && make

Сборка и запуск:

docker build -t myproject .

docker run -it --rm -v $(pwd):/app myproject


6. Советы по оптимизации сборки

  1. Инкрементальная сборка: Не пересобирайте весь проект, если изменился только один файл. Инструменты вроде make и ninja поддерживают это "из коробки".

  2. Параллельная сборка: Используйте флаг -j для ускорения сборки на многоядерных процессорах:

    make -j$(nproc)

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

  4. Статическая vs Динамическая линковка: Выбирайте подходящий метод в зависимости от ваших целей:

    • Статическая линковка создает автономный исполняемый файл, но увеличивает его размер.

    • Динамическая линковка делает файл меньше, но требует наличия библиотек на целевой системе.


7. Заключение

Настройка сборки проекта — это инвестиция в будущее. Чем раньше вы потратите время на её автоматизацию, тем проще будет развивать проект. Вот несколько рекомендаций:

  • Для небольших проектов используйте Makefile.

  • Для средних и больших проектов выбирайте CMake или Meson.

  • Если вам нужно тестировать сборку в разных окружениях, используйте Docker.

  • Всегда документируйте процесс сборки, чтобы другие разработчики могли легко подключиться к проекту.

Помните: хороший процесс сборки — это залог стабильности и успеха вашего проекта!

Показать полностью
[моё] Программирование Гайд IT Windows C++ Сборка Длиннопост
0
4
mcnikirikitiki
4 месяца назад
Лига программистов

Основы программирования на C++: составные типы данных, ссылки и указатели⁠⁠

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

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

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

  • Составные типы данных : перечисления, структуры, кортежи и пары.

  • Ссылки и указатели : как они работают и зачем нужны.

  • Константность : как использовать const для создания надежного кода.

  • Дополнительные темы : динамическая память, умные указатели и практические советы.


1. Составные типы данных

Перечисления

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

enum class Color {

White,

Red,

Orange,

Blue,

};

Теперь вы можете использовать эти значения через префикс Color:::

Color color = Color::Red;

По умолчанию значения перечислений хранятся как целые числа, начиная с нуля. Их можно преобразовать в числа и обратно с помощью static_cast:

int value = static_cast<int>(color); // Преобразование в число

Color color2 = static_cast<Color>(2); // Преобразование обратно

Структуры

Структуры позволяют объединять несколько переменных под одним именем. Например, если вы работаете с точками в трехмерном пространстве, можно создать структуру:

struct Point {

double x = 0.0;

double y = 0.0;

double z = 0.0;

Color color; // Цвет точки

};

Инициализировать структуру можно несколькими способами:

Point point1 = {1.4, -2.2, -3.98, Color::Red};

Point point2 = {.x = 1.4, .y = -2.2}; // C++20 и выше

Кортежи и пары

Для хранения нескольких значений можно использовать std::pair или std::tuple:

#include <tuple>

std::tuple<int, double, Color> t = {42, 3.14, Color::Orange};

std::cout << std::get<0>(t); // Выведет 42

Выравнивание данных

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

struct Point {

double x; // 8 байт

double y; // 8 байт

double z; // 8 байт

int color; // 4 байта

};

Размер этой структуры будет 32 байта, а не 28, потому что компилятор добавляет "пустые" байты для выравнивания.


2. Ссылки и указатели

Ссылки

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

int x = 42;

int& ref = x; // Теперь ref — это другое имя для x

ref = 10; // Изменит значение x

Ссылки удобны для работы с большими объектами, такими как строки или векторы, чтобы избежать копирования:

std::string s1 = "Hello";

std::string& s2 = s1; // s2 — это ссылка на s1

s2 += " World"; // Изменит s1

Указатели

Указатель хранит адрес переменной в памяти. Его можно получить с помощью оператора &:

int x = 42;

int* ptr = &x; // ptr хранит адрес x

std::cout << *ptr; // Разыменование: выведет 42

Указатели можно переназначать, а также использовать специальное значение nullptr, которое означает "пустой" указатель:

int* ptr = nullptr; // Пустой указатель

ptr = &x; // Теперь ptr указывает на x

Опасности указателей

Не обращайтесь к памяти, которая уже вышла из области видимости:

int* ptr = nullptr;

{

int x = 42;

ptr = &x;

}

// *ptr — неопределённое поведение!


3. Константность

Константы — это переменные, которые нельзя изменять после инициализации:

const int c = 42;

// c = 10; // Ошибка компиляции

Константность можно комбинировать со ссылками и указателями:

const int* ptr = &x; // Указатель на константу

int* const ptr = &x; // Константный указатель


4. Дополнительные темы

Динамическая память

Динамическая память используется, когда размер данных заранее неизвестен. Для этого применяются операторы new и delete:

int* arr = new int[10]; // Выделение памяти

delete[] arr; // Освобождение памяти

Умные указатели

Умные указатели (std::unique_ptr, std::shared_ptr) автоматически освобождают память, когда она больше не нужна:

#include <memory>

std::unique_ptr<int> ptr = std::make_unique<int>(42);

Практические советы

  1. Используйте ссылки в циклах :

    for (const auto& item : vector) {

    std::cout << item;

    }

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

  3. Проверяйте границы массивов : Используйте метод at() вместо оператора [], чтобы избежать ошибок доступа.

Задачи для практики

1. Перечисления: "Трафик-свет"

Описание:
Создайте программу, которая моделирует работу светофора. Используйте перечисление enum class TrafficLight с тремя состояниями: Red, Yellow, Green. Программа должна циклически переключать светофор каждую секунду (можно использовать std::this_thread::sleep_for для задержки).

Пример вывода:

Red

Yellow

Green

Red

...


2. Структуры: "Координаты точек"

Описание:
Создайте структуру Point3D, которая представляет точку в трехмерном пространстве. Добавьте метод distanceTo, который вычисляет расстояние между двумя точками.

Пример использования:

Point3D p1 = {1.0, 2.0, 3.0};

Point3D p2 = {4.0, 5.0, 6.0};

std::cout << p1.distanceTo(p2); // Выведет ~5.196


3. Кортежи и пары: "Анализ данных"

Описание:
Напишите программу, которая хранит информацию о студентах в виде кортежей. Каждый кортеж содержит имя студента (строка), возраст (целое число) и средний балл (число с плавающей точкой). Создайте вектор таких кортежей и найдите студента с максимальным средним баллом.

Пример данных:

std::vector<std::tuple<std::string, int, double>> students = {

{"Alice", 20, 4.5},

{"Bob", 22, 3.8},

{"Charlie", 21, 4.9}

};

Пример вывода:

Студент с максимальным баллом: Charlie, балл: 4.9


4. Указатели: "Менеджер памяти"

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

Дополнительно:
Добавьте проверку на утечку памяти (например, используя инструменты, такие как Valgrind или AddressSanitizer).


5. Константность: "Защита данных"

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

Пример использования:

std::vector<int> nums = {1, 2, 3, 4, 5};

printVector(nums);

Пример вывода:

1 2 3 4 5


6. Умные указатели: "Управление ресурсами"

Описание:
Создайте класс FileHandler, который управляет открытием и закрытием файла. Используйте std::unique_ptr для автоматического управления ресурсами.

Пример использования:

FileHandler file("example.txt");

file.write("Hello, world!");


7. Ссылки в циклах: "Фильтрация данных"

Описание:
Напишите программу, которая фильтрует строки из вектора, оставляя только те, которые начинаются с заглавной буквы. Используйте ссылки в цикле for для эффективной работы с данными.

Пример данных:

std::vector<std::string> words = {"Apple", "banana", "Cherry", "date"};

Пример вывода:

Apple

Cherry


8. Выравнивание данных: "Размер структуры"

Описание:
Создайте структуру с полями разных типов (например, char, int, double) и выведите её размер с помощью sizeof. Затем измените порядок полей так, чтобы минимизировать размер структуры за счет выравнивания.

Пример структуры:

struct Example {

char c;

double d;

int i;

};

Пример вывода:

Исходный размер: 24 байта

Оптимизированный размер: 16 байт


9. "Висячие" ссылки: "Безопасное обращение"

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

Пример кода:

int* ptr = nullptr;

{

int x = 42;

ptr = &x;

}

std::cout << *ptr; // Неопределенное поведение!


10. Комбинированная задача: "Управление библиотекой"

Описание:
Создайте программу для управления библиотекой книг. Каждая книга описывается структурой Book с полями: название, автор, год издания. Реализуйте следующие функции:

  1. Добавление книги в библиотеку.

  2. Поиск книги по названию.

  3. Удаление книги из библиотеки.

Используйте std::vector для хранения книг и умные указатели для управления памятью.

Пример использования:

Library lib;

lib.addBook({"The C++ Programming Language", "Bjarne Stroustrup", 1985});

lib.findBook("The C++ Programming Language");

lib.removeBook("The C++ Programming Language");


Заключение

Теперь вы знаете основы работы с составными типами данных, ссылками, указателями и константностью в C++. Эти инструменты — фундамент для написания эффективного кода. Продолжайте практиковаться, и скоро вы сможете создавать сложные программы!

Показать полностью
[моё] IT Программирование Гайд C++ Указатель Длиннопост
4
6
mcnikirikitiki
4 месяца назад
Лига программистов

Основы C++: Ветвления, Циклы, Векторы и Строки⁠⁠

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

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

Здравствуйте, мои маленькие любители программирования!

Сегодня мы разберем ключевые конструкции C++: ветвления , циклы , векторы и строки . Это как азбука программиста — без них никуда. Готовы? Погнали!


1. Ветвления: если «если», то идем дальше

В жизни мы постоянно принимаем решения: «Если дождь — возьми зонт», «Если голоден — поешь». В C++ для этого есть операторы if, else if, else и switch.

1.1. Оператор if

Простейший пример:

if (x > 0) {

std::cout << "Число положительное!\n";

} else {

std::cout << "Число не положительное...\n";

}

Важно:

  • Фигурные скобки {} можно не ставить, если внутри одна строка. Но лучше ставить всегда — так меньше ошибок.

  • Условия можно комбинировать через && (и), || (или), ! (не).

Пример сложного условия:

if ((age >= 18 && age <= 65) || hasSpecialPermission) {

// Условие читается как:

// "Если возраст от 18 до 65 ИЛИ есть специальное разрешение"

}

1.2. Оператор switch

Идеален для выбора из множества вариантов:

switch (operation) {

case '+':

result = a + b;

break;

case '-':

result = a - b;

break;

default:

result = 0; // если ни один case не подошел

}

Важно:

  • Не забудьте break, иначе выполнение «провалится» в следующий case.

  • switch работает только с целыми числами и символами. Со строками — нельзя!

1.3. goto — зло?

Да, его лучше не использовать. Но для примера:

again:

std::cout << "Введите возраст: ";

int age;

std::cin >> age;

if (age < 0) goto again; // прыжок на метку again

Совет: Вместо goto используйте циклы. Они читабельнее и безопаснее.


2. Циклы: повторяем, пока не надоест

Циклы нужны, чтобы выполнять код много раз. В C++ их три вида: while, do-while, for.

2.1. Цикл while

Проверяет условие перед итерацией:

int n = 1;

while (n <= 10) {

std::cout << n << " ";

++n;

}

// Вывод: 1 2 3 ... 10

2.2. Цикл for

Идеален для перебора элементов:

for (int i = 1; i <= 10; ++i) {

std::cout << i << " ";

}

Фишка: Можно использовать range-based for для контейнеров:

std::string line = "Hello";

for (char c : line) {

std::cout << c << " "; // H e l l o

}

2.3. break и continue

  • break — досрочный выход из цикла.

  • continue — переход к следующей итерации.

Пример:

while (true) {

int x;

std::cin >> x;

if (x == 0) break; // выход при вводе 0

if (x < 0) continue; // пропуск отрицательных

std::cout << x << " ";

}


3. Векторы: динамические массивы

std::vector — это массив, который умеет расти. Подключаем через <vector>.

3.1. Создание и доступ

std::vector<int> nums = {1, 2, 3};

nums.push_back(4); // добавляем 4 в конец

std::cout << nums[0]; // 1 (первый элемент)

std::cout << nums.size(); // 4 (размер вектора)

Важно:

  • Обращение по неверному индексу (nums[10]) — неопределенное поведение.

  • Используйте at() для проверки границ: nums.at(10) выбросит исключение.

3.2. Дополнительные методы

std::vector<int> v = {1, 2, 3};

v.empty(); // проверка на пустоту

v.clear(); // очистка вектора

v.reserve(100); // резервирование места для 100 элементов

v.capacity(); // текущая ёмкость

3.3. Сортировка вектора

#include <algorithm>

std::vector<int> data = {3, 1, 4};

std::sort(data.begin(), data.end()); // 1, 3, 4


4. Строки: не просто символы

std::string — это вектор символов с дополнительными функциями. Подключаем через <string>.

4.1. Основные операции

std::string s = "Hello";

s += " World!"; // "Hello World!"

std::cout << s.substr(6, 5); // "World" (подстрока)

size_t pos = s.find("World"); // позиция = 6

4.2. Дополнительные методы

std::string s = "Hello";

s.size(); // длина строки

s.empty(); // проверка на пустоту

s.append(" World"); // добавление

s.erase(0, 1); // удаление символа по индексу

s.replace(0, 5, "Hi"); // замена подстроки

s.find_first_of("aeiou"); // поиск первой гласной

4.3. Палиндром? Легко!

#include <algorithm>

std::string word = "радар";

std::string reversed = word;

std::reverse(reversed.begin(), reversed.end());

if (word == reversed) {

std::cout << "Это палиндром!\n";

}


Практика: 5 задач для закрепления

Задача 1: «Сумматор»

Описание: Напишите программу, которая суммирует все числа, введенные пользователем, пока не будет введен 0. Пример:

Введите числа: 5 3 -2 0

Сумма: 6

Задача 2: «Поиск максимума»

Описание: Создайте вектор из 10 случайных чисел (от 1 до 100). Найдите максимальный элемент. Подсказка: Используйте rand() % 100 + 1 для генерации чисел.

Задача 3: «Шифратор»

Описание: Напишите программу, которая заменяет все гласные буквы в строке на символ '*'. Пример:

Введите строку: Hello

Результат: H*ll*

Задача 4: «Калькулятор»

Описание: Реализуйте простой калькулятор, который принимает два числа и операцию (+, -, *, /). Используйте switch для обработки операций.

Задача 5: «Удаление пробелов»

Описание: Напишите программу, которая удаляет все пробелы из введенной строки. Пример:

Введите строку: Hello World

Результат: HelloWorld


Заключение

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

Показать полностью
[моё] Программирование Гайд C++ IT Длиннопост
2
7
mcnikirikitiki
4 месяца назад
Лига программистов

Знакомство с C++⁠⁠

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

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

Заранее благодарю за понимание.

Здравствуйте, мои маленькие любители программирования.

Итак, C++ — это язык, которому почти 40 лет. Да-да, он старше многих из вас! Но, как говорится, возраст — это просто число. C++ до сих пор остается актуальным и востребованным. Он был создан Бьярне Страуструпом (да благословит его каждый программист) как расширение языка C. Изначально он даже назывался "Си с классами". Но чтобы начать учить C++, совсем не обязательно знать C. Хотя, конечно, базовые знания программирования вам понадобятся. Например, можно быть знакомым с Python — этим милым, дружелюбным языком, который так любят в школах.

Но вот парадокс: C++ во многом полная противоположность Python. Если Python — это интерпретируемый язык, где вы пишете код и сразу видите результат, то C++ — компилируемый. Это значит, что перед запуском программы вам нужно скомпилировать ее. Звучит сложно? На самом деле нет. Просто представьте, что компилятор — это переводчик, который превращает ваш красивый код в язык, понятный процессору.

Кстати, о компиляторах. Есть несколько популярных вариантов: GCC, Clang, MSVC и другие. Мы будем использовать Clang 16-й версии. Почему? Потому что он удобный, быстрый и просто крутой. При проверке задач мы будем использовать такие ключи компиляции:

clang++ --std=c++20 -O3 -fsanitize=address,undefined -Wall -Wextra -Werror

Не пугайтесь этих строчек! Это просто настройки, которые помогают находить ошибки и делать ваш код лучше.

Теперь немного о стандартах. C++ развивается, и каждые несколько лет появляется новый стандарт языка. Мы будем ориентироваться на C++20. Это как последняя версия вашего любимого приложения — только для программистов.

Если вы думаете, что написание программ на C++ требует каких-то особенных инструментов, то вы ошибаетесь. Можно писать код даже в блокноте. Но, конечно, удобнее использовать среду разработки (IDE). Например, Visual Studio, Eclipse или Qt Creator. Мы же будем запускать компилятор прямо из консоли. Так вы почувствуете себя настоящими хакерами из фильмов.

А теперь давайте напишем нашу первую программу. Знаете, что это будет? Конечно же, "Hello, world!" — традиция, которую обязан соблюдать каждый программист. Вот она:

#include <iostream>

int main() {

std::cout << "Hello, world!\n";

}

Выглядит просто, правда? Но давайте разберем, что здесь происходит. #include <iostream> — это подключение библиотеки для работы с потоками ввода-вывода. std::cout — это поток вывода, который отправляет текст на экран. А \n — это символ перевода строки.

Чтобы скомпилировать эту программу, откройте терминал и введите:

clang++ hello.cpp -o hello

После этого запустите исполняемый файл:

./hello

И вот оно — магическое сообщение: "Hello, world!"

Но что, если вы хотите сделать программу чуть интереснее? Например, спросить имя пользователя и поприветствовать его персонально? Тогда вам понадобится поток ввода std::cin. Вот пример:

#include <iostream>

#include <string>

int main() {

std::string name;

std::cout << "What is your name?\n";

std::cin >> name;

std::cout << "Hello, " << name << "!\n";

}

Обратите внимание: если пользователь введет несколько слов через пробел, программа "увидит" только первое. Чтобы считать всю строку целиком, используйте функцию std::getline.

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

Переменные и типы данных

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

  • int — целые числа (например, 42).

  • float и double — числа с плавающей точкой (дробные числа). float обычно занимает 4 байта, а double — 8.

  • char — символы (например, 'A').

  • bool — логический тип, принимающий значения true или false.

Пример объявления переменных:

int age = 25;

double pi = 3.14159;

char grade = 'A';

bool isProgrammer = true;

Обратите внимание: в C++ важно инициализировать переменные перед их использованием. Если этого не сделать, то при попытке чтения значения такой переменной может возникнуть неопределенное поведение (UB — undefined behavior).

Области видимости

В C++ существует понятие области видимости (scope) переменной. Это означает, что переменная доступна только внутри блока кода, в котором она была объявлена. Например:

#include <iostream>

int globalVariable = 1; // Глобальная переменная

int main() {

int localVariable = 2; // Локальная переменная

{

int innerVariable = 3; // Локальная переменная внутри блока

std::cout << globalVariable << " " << localVariable << " " << innerVariable << "\n";

}

// Здесь innerVariable недоступна

std::cout << globalVariable << " " << localVariable << "\n";

}

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

Арифметические операции

C++ поддерживает все стандартные арифметические операции: сложение (+), вычитание (-), умножение (*), деление (/) и взятие остатка от деления (%). Пример:

int a = 7, b = 3;

int sum = a + b; // 10

int difference = a - b; // 4

int product = a * b; // 21

int quotient = a / b; // 2 (целочисленное деление)

int remainder = a % b; // 1 (остаток от деления)

Если вам нужно работать с дробными числами, используйте тип double и явное приведение типов:

double exactQuotient = static_cast<double>(a) / b; // 2.333...

Условия и циклы

Одним из ключевых элементов программирования являются условия и циклы. Они позволяют управлять потоком выполнения программы. Вот пример использования условного оператора if:

int number = 10;

if (number > 0) {

std::cout << "Число положительное.\n";

} else if (number < 0) {

std::cout << "Число отрицательное.\n";

} else {

std::cout << "Число равно нулю.\n";

}

Циклы позволяют повторять выполнение блока кода несколько раз. Вот пример цикла for, который выводит числа от 1 до 5:

for (int i = 1; i <= 5; ++i) {

std::cout << i << "\n";

}

А вот пример цикла while, который выполняется, пока условие истинно:

int counter = 0;

while (counter < 5) {

std::cout << "Счетчик: " << counter << "\n";

++counter;

}

Задача 1: "Калькулятор"

Описание: Напишите программу, которая принимает два числа и операцию (сложение, вычитание, умножение или деление) от пользователя, а затем выводит результат.

Пример работы программы:

Введите первое число: 10

Введите второе число: 5

Выберите операцию (+, -, *, /): *

Результат: 50

Подсказка: Используйте std::cin для ввода данных и условный оператор if для выбора операции. Не забудьте обработать деление на ноль!


Задача 2: "Угадай число"

Описание: Напишите программу, которая загадывает случайное число от 1 до 100 и предлагает пользователю угадать его. После каждой попытки программа должна сообщать, было ли число больше или меньше загаданного.

Пример работы программы:

Я загадал число от 1 до 100. Попробуйте угадать!

Ваша догадка: 50

Мое число меньше.

Ваша догадка: 25

Мое число больше.

Ваша догадка: 30

Поздравляю! Вы угадали за 3 попытки!

Подсказка: Для генерации случайного числа используйте функцию rand() из заголовочного файла <cstdlib>. Чтобы сделать число действительно случайным, добавьте вызов srand(time(0)) из <ctime> в начале программы.


Задача 3: "Факториал"

Описание: Напишите программу, которая вычисляет факториал числа, введенного пользователем. Факториал числа n (обозначается как n!) — это произведение всех целых чисел от 1 до n. Например, 5!=5×4×3×2×1=120.

Пример работы программы:

Введите число: 5

Факториал числа 5 равен 120.

Подсказка: Используйте цикл for для вычисления произведения. Обратите внимание, что факториал определен только для неотрицательных целых чисел.

Задача 4: "Таблица умножения"

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

Пример работы программы:

Введите число: 7

Таблица умножения для числа 7:

7 x 1 = 7

7 x 2 = 14

7 x 3 = 21

...

7 x 10 = 70

Подсказка: Используйте цикл for для перебора множителей от 1 до 10.

Задача 5: "Сумма цифр числа"

Описание: Напишите программу, которая принимает целое число и вычисляет сумму его цифр.

Пример работы программы:

Введите число: 1234

Сумма цифр числа 1234 равна 10.

Подсказка: Преобразуйте число в строку с помощью std::to_string, чтобы легко получить доступ к каждой цифре. Альтернативно, используйте операции деления и взятия остатка для работы с числами напрямую.


Задача 6: "Палиндром"

Описание: Напишите программу, которая проверяет, является ли введенная строка палиндромом. Палиндром — это слово или фраза, которые читаются одинаково слева направо и справа налево.

Пример работы программы:

Введите строку: радар

Строка "радар" является палиндромом.

Введите строку: hello

Строка "hello" не является палиндромом.

Подсказка: Используйте функцию std::reverse из заголовочного файла <algorithm> для создания перевернутой версии строки. Сравните исходную строку с перевернутой.


Задача 7: "Игра в кости"

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

Пример работы программы:

Бросаем кости...

Первая кость: 4

Вторая кость: 6

Общее количество очков: 10

Подсказка: Используйте функцию rand() для генерации случайных чисел от 1 до 6.

Показать полностью
[моё] Гайд Программирование C++ IT Длиннопост
16
7
Sigurd2012
Sigurd2012
4 месяца назад
Timeend

Мой вариант "Змейки" на С++ (пока предварительный)⁠⁠

А вот мой мини-мультсериал "в стиле старых игр" (тоже С++):

  • Retro Game Stories - 5 серий

Показать полностью
[моё] Игры Ретро-игры Программирование C++ Игра змейка Видео Без звука
3
8
0sadchi
0sadchi
5 месяцев назад
Лига Разработчиков Видеоигр

Свой Cheat Engine с нуля! Часть 1 - Получаем список процессов и модули в нем⁠⁠

Чтобы сформировать понимание, как происходит получение списка процессов, просто заглянем в исходники самого Cheat Engine.

Здесь у нас есть процедура GetProcessList, в которую мы подаем массив строк, в который она запишем нам имена и айди процессов.

Первое, на что обратим внимание - структура, куда записывается информация о процесе, в СЕ она выглядит так

Свой Cheat Engine с нуля! Часть 1 - Получаем список процессов и модули в нем Windows, Программирование, Cheat Engine, C++, Hacking, Длиннопост

Мы можем ее записать так.

Свой Cheat Engine с нуля! Часть 1 - Получаем список процессов и модули в нем Windows, Программирование, Cheat Engine, C++, Hacking, Длиннопост

Далее в процедуре идет блок с переменными

Свой Cheat Engine с нуля! Часть 1 - Получаем список процессов и модули в нем Windows, Программирование, Cheat Engine, C++, Hacking, Длиннопост

Как итог я оставил так

Свой Cheat Engine с нуля! Часть 1 - Получаем список процессов и модули в нем Windows, Программирование, Cheat Engine, C++, Hacking, Длиннопост

Для замены под C++ объекта ProcessList: TStrings, я использовал std::unordered_map<std::wstring, PProcessListInfo>& process_list. Потому что в коде, была логика схожая с мапой, когда у нас по имени процесса идет связка с объектом, содержащим информацию о нем (фактически один ProcessID..)

Свой Cheat Engine с нуля! Часть 1 - Получаем список процессов и модули в нем Windows, Программирование, Cheat Engine, C++, Hacking, Длиннопост

Что у нас эквивалентно

Свой Cheat Engine с нуля! Часть 1 - Получаем список процессов и модули в нем Windows, Программирование, Cheat Engine, C++, Hacking, Длиннопост

И в конце при необходимости это включается в лист

Свой Cheat Engine с нуля! Часть 1 - Получаем список процессов и модули в нем Windows, Программирование, Cheat Engine, C++, Hacking, Длиннопост

Заменил на

Свой Cheat Engine с нуля! Часть 1 - Получаем список процессов и модули в нем Windows, Программирование, Cheat Engine, C++, Hacking, Длиннопост

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

Но тут мое любопытство увело меня в сторону от Cheat Engine, и я решил посмотреть, что там у Process Hacker, это утилита позволяет работать с процессами. Самой интересной частью является - список модулей. Потому, что там сразу можно увидеть кто-где и какой размер в памяти занимает каждый из них.

Через поиск по файла по фразе EnumModules я вышел на вот такую вот функцию

Свой Cheat Engine с нуля! Часть 1 - Получаем список процессов и модули в нем Windows, Программирование, Cheat Engine, C++, Hacking, Длиннопост

так же у нее есть 32битная реализация

Свой Cheat Engine с нуля! Часть 1 - Получаем список процессов и модули в нем Windows, Программирование, Cheat Engine, C++, Hacking, Длиннопост

Результатом работы оных будет вот такая вот структура

Свой Cheat Engine с нуля! Часть 1 - Получаем список процессов и модули в нем Windows, Программирование, Cheat Engine, C++, Hacking, Длиннопост
Свой Cheat Engine с нуля! Часть 1 - Получаем список процессов и модули в нем Windows, Программирование, Cheat Engine, C++, Hacking, Длиннопост

Самыми интересными для нас будут PVOID DllBase - начало модуля относительно процесса , ULONG SizeOfImage - размер модуля (сколько байт он занимает внутри процесса) и UNICODE_STRING FullDllName. Но с именем все не так просто. Структура выглядит так

Свой Cheat Engine с нуля! Часть 1 - Получаем список процессов и модули в нем Windows, Программирование, Cheat Engine, C++, Hacking, Длиннопост

Казалось бы, вот же она.. PWSTR Buffer строка.. выводись в студаут!! А вот и нет, здесь находится адрес в чужом пространстве, чтобы прочитать эту строку, придется сделать следующее.

Свой Cheat Engine с нуля! Часть 1 - Получаем список процессов и модули в нем Windows, Программирование, Cheat Engine, C++, Hacking, Длиннопост

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

Все, до чего я докопался - это метод

Свой Cheat Engine с нуля! Часть 1 - Получаем список процессов и модули в нем Windows, Программирование, Cheat Engine, C++, Hacking, Длиннопост

Данные о драйвере выглядят так

Свой Cheat Engine с нуля! Часть 1 - Получаем список процессов и модули в нем Windows, Программирование, Cheat Engine, C++, Hacking, Длиннопост

Но, к сожалению, с наскока подключиться к драйверу не удалось и лучший ответ, который я получилъ

Свой Cheat Engine с нуля! Часть 1 - Получаем список процессов и модули в нем Windows, Программирование, Cheat Engine, C++, Hacking, Длиннопост

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

Конец! А кто слушал - можете прокачать свои навыки на крутейшем курсе по реверсу ММОРПГ :)

Показать полностью 15
[моё] Windows Программирование Cheat Engine C++ Hacking Длиннопост
2
Партнёрский материал Реклама
specials
specials

Как бросить курить и не сорваться: инструкция от тех, кто смог⁠⁠

Выходишь покурить на пять минут, а возвращаешься через 10 лет: с хрипом, тремя неудачными попытками бросить и пачкой мятных жвачек в кармане. Это как плохой сериал: тянется слишком долго, а финал все равно разочарует. Но выйти из этого сценария можно и даже не обязательно драматично. Мы собрали истории тех, кто боролся с зависимостью ради любимого человека, здоровья или лучшей жизни.

Как бросить курить и не сорваться: инструкция от тех, кто смог Курение, Борьба с курением, Зависимость, Telegram (ссылка), ВКонтакте (ссылка), Длиннопост

История 1 — отражение

@ holoroad

Маленькая дочка почти научилась ходить и всюду телепалась за мной. Я не курил при ней. Ходил на балкон, а она, прильнув к стеклу, смотрела на меня и ждала, когда я докурю и выйду к ней. И в какой-то момент она начала повторять за мной вот эти движения. Маленький человечек, ей было года полтора или два, прикладывала воображаемую сигарету к губам, а потом делала вид, что выпускает дым. И весело так на меня смотрела, сквозь стекло балконной двери. Ей нравилось все, что со мной связано, и она подражала всем моим действиям. Я курил уже двадцать лет и, конечно, делал множество попыток бросить до этого. Но в этот раз у меня в первый раз появилась по-настоящему важная причина бросить. Это важно для человека, который безгранично мне доверяет. С тех пор прошло почти десять лет, в течение которых я не сделал ни одной затяжки.

Решение бросить курить — одно из лучших, которое вы можете принять для своего здоровья, будущего и близких. Но справиться с зависимостью только потому, что «это вредно» будет тяжело. А вот если хотите не задыхаться, поднимаясь по лестнице, или волнуетесь за своего ребенка, которые вдыхает табачный дым, — уже другое дело.

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

История 2 — список

@ maxneb

Беременность жены, рождение ребенка, здоровье, деньги — ничего не было веским поводом бросить окончательно. Постоянно срывался. Помогло составить список, что теряю и что получаю от сигарет, и понимание, что хотя бы одна затяжка — и все насмарку: пару месяцев буду курить. Только список и его осознание. Для каждого он свой. И постоянное обращение к нему. После составления списка курил еще. Но он как заноза висел в голове с вопросом «зачем?»... Так, что-то щелкнуло и сейчас не тянет. Иногда тянет физически, но осознание бесполезности курения сразу глушит позывы. Полгода, полет нормальный...

Бросать на авось — идея, которая подойдет не всем. Нужно понимать, что делать в трудные моменты:

  • Определите дату отказа. Подготовьтесь морально, уберите сигареты, зажигалки, пепельницы.

  • Замените привычки. Сигарету в руках можно заменить орешками, палочками морковки, жвачкой или даже кубиком льда.

  • Займите время. Вспомните, чем вы любили заниматься: спорт, хобби, прогулки.

  • Планируйте, что делать при тяге. Она длится всего 3–5 минут. Дыхательные практики или звонок другу помогут пережить сильное желание закурить.

  • Откажитесь от «наградных сигарет». Одна затяжка и вы откатитесь назад.

Можно бросить резко, «с понедельника», или постепенно, снижая количество сигарет до нуля. Главное — определиться и не отступать.

История 3 — переключение

@ Spaka

45 лет, стаж 30. Пытался завязать много раз, потом понял, что после каждой попытки бросить, курить начинаешь больше. Как ребенок, которому не дают вкусняшку, а она случайно попала ему в руки. Из чего мозг сделал вывод: не уверен — не бросай. Потом стал замечать, что организм уже стал сам просить перестать курить. По утрам было очень неприятно во рту, удовольствие после сигареты стало короче, а негатив, приходящий следом, ощутимее: неприятные ощущения в горле, боли миндалин, страх схватить онкодиагноз. Хотя врачи говорили, что все ок, в голове-то гоняешь мысли. Я решил попробовать обмануть сам себя. Не делать из процесса отказа какого-то события. Бросить так, как будто это и должно было произойти, но ты не знаешь когда. Про себя помолился, как сумел, и попросил помощи, хитро прищурил глаз и в момент, когда забыл купить про запас (оставалась пара штук в пачке), просто перестал курить. Мне теперь даже странно, как я раньше это делал. Так и живу почти два года. Кстати, раньше в момент завязки курящих ненавидел, дым был очень противен, до тошноты. Теперь все равно. Присоединяйтесь ;)

Есть несколько стратегий отказа от курения:

  • Резкий. Эффективный и решительный подход.

  • Постепенный. Сначала — меньше сигарет, потом — меньше затяжек. И так до нуля.

  • Психологическая замена. Каждая сигарета — это ритуал. Найдите для каждого из них «здоровую замену».

  • Медикаментозная терапия. При сильной зависимости врач может порекомендовать никотинозаместительную терапию (пластыри, таблетки, жвачки) или препараты, которые помогают справиться с синдромом отмены. Но любые лекарства принимаются только по рекомендации специалиста.

Каждый, кто хочет оставить зависимость в прошлом, может обратиться в центры здоровья, которые работают при поддержке нацпроекта «Продолжительная и активная жизнь», и получить необходимую помощь специалистов. Адреса доступны на официальном портале Минздрава России о здоровье: takzdorovo.ru. Также можно позвонить на горячую линию по отказу от зависимостей 8 800 200-0-200.

История 4 — форма

Аноним

Курила электронки 2 года как замену обычным сигаретам. Думала, что это не так дорого, не так вредно да и для девушки вроде более привлекательно: не пахнут волосы и руки. А потом решила привести свое тело в форму. Стала ходить в зал и поняла, что задыхаюсь на первом же упражнении, хотя женщины гораздо старше меня бодрячком. Было очень тяжело слезть. Друзья советовали заменять сигаретами. А потом уехала в отпуск в страну, где нельзя покупать электронки, отвлеклась, и после возвращения уже не тянуло. Даже на тусовках, где все дымят.

За модными гаджетами и фруктовыми ароматами скрывается химическая бомба, разрушающая организм быстрее, чем обычные сигареты. Электронные сигареты активно продвигаются производителями как «безопасная» альтернатива сигаретам. Но курение вейпа может обернуться серьезными проблемами: от кашля и одышки до поражения сосудов и дыхательных путей.

«Особую тревогу вызывает рост потребления табачных изделий и электронных сигарет. Согласно исследованию, проведенному в нашем Центре, 36,8% курильщиков потребляют одновременно и табак, и электронные сигареты. Среди молодежи в возрасте 25-39 лет этот показатель превышает 45%. Электронные никотиносодержащие и безникотиновые устройства поражают сердце, сосуды, дыхательную систему и ДНК организма не менее пагубно, чем традиционные сигареты, а в ряде случаев способны вызывать острые состояния, включая сосудистые поражения и летальные исходы» – рассказывает руководитель Центра профилактики и контроля потребления табака НМИЦ терапии и профилактической медицины Минздрава России Маринэ Гамбарян.

История 5 — пари

@ kernima

Вроде не было никаких серьезных предпосылок, чтобы бросить. Да и чтобы начать: просто все вокруг курили, думал, это сейчас тренд. А потом как-то сидели в баре и решили поспорить с некурящим другом. Он затирал, что моя жизнь из-за электронки катится ко дну, я — доказывал, что это всего лишь маленькая шалость. В общем поспорили на пять тысяч. Чтобы было легче и можно было отвлечься, начал бегать по утрам. Друг проиграл, а я возвращаться к курению не стал. Вдруг снова у еды появился вкус, я начал высыпаться и больше не устаю на втором лестничном проеме. Короче, советую!))

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

Когда организм отвыкает от никотина, бывает нелегко: люди становятся раздражительным и нервозными, быстро устают, возникают сухость во рту, кашель, трудности с концентрацией. Важную роль в борьбе с этими симптомами играет питание. В рацион стоит включить овощи, фрукты, орехи, семечки. Клетчатка способствует очищению организма от токсинов. Важно питаться сбалансировано: с достаточным количеством белков, жиров, углеводов и витаминов. Лучше временно исключить продукты, усиливающие удовольствие от табака (например, мясо), а также отказаться от алкоголя, кофе и крепкого чая. Они могут спровоцировать желание закурить. А вот большое количество воды, травяных чаев и настоев облегчит очищение организма и поможет справиться с сухостью во рту.

История 6 — связь

Аноним

Устал курить, понял, что мне это мешает заниматься спортом и в целом комфортно себя чувствовать. Пошел через ассоциации: покурил во время головной боли, и потом через самовнушение дал себе установку, что голова болела от курения. Звучит странно, конечно, но это сработало. Никотиновую зависимость снижал постепенно через редкое курение кальяна (2-3 раза в неделю с последующим уменьшением).

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

Разберитесь, что именно тянет вас к сигарете: скука, стресс, привычка? Когда вы это осознаете, будет легче подобрать альтернативные действия — прогулку, книгу, разговор с близким. Учитесь распознавать моменты, когда особенно хочется закурить, и переключаться на что-то другое. Можно подключиться к программам или группам поддержки — это поможет не сдаваться. И главное: уберите из дома все сигареты.

История 7 — вершина

Аноним

Поднимался с сыном по Пушкинской тропе на гору Железная. Мне лет сорок пять было, идем общаемся, сын бегает туда-сюда. Ну идем короче, а сзади нас догоняет семейная пара, мирно о чем-то щебеча между собой. Догнали и обходят. И так спокойно удаляются… Все бы ничего, но им лет по шестьдесят, если не больше. Я попробовал в их темпе, но задыхаться стал. Короче, поднялся я на гору, спустился, смял пачку и выкинул в мусорную урну. Вот уже 13 лет не курю. Стаж 27 лет.

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


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

Хорошая новость в том, что вы не одни. В сообществе «Давай бросать» (ВКонтакте и мессенджере Telegram), который работает при поддержке нацпроекта «Продолжительная и активная жизнь» знают, каково бороться с триггерами, искать замену привычке и удерживать себя от срыва. Здесь делятся историями тех, кто смог, поддерживают тех, кто только начал, и помогают разобраться в главном: как пережить отказ без мучений.

Социальная реклама. АНО «Национальные приоритеты», ИНН: 9704007633

Показать полностью
Курение Борьба с курением Зависимость Telegram (ссылка) ВКонтакте (ссылка) Длиннопост
3
georgiyozhegov
georgiyozhegov
5 месяцев назад
Лига программистов
Серия Программирование

Читщит По Умным Указателям⁠⁠

Читщит По Умным Указателям Обучение, Rust, Программирование, C++, Длиннопост

Наглядная иллюстрация того, что может случиться с C++ программистами.

В Rust необычная схема управления памятью. Он не использует сборщик мусора, как в Java и Go, что делает его быстрым. Скорость Rust сопоставима со скоростью C.

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

В статье специально использованы простейшие примеры, чтобы понять их было легче.

Типы

Box

Нужен для хранения объектов в куче, а не на стеке.

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

Пример кода, который не будет работать.

struct Expression {

operator: Operator,

left: Expression, // Ошибка: recursive type has infinite size

right: Expression, // Ошибка: recursive type has infinite size

}

Чинится обертыванием left и right в Box.

struct Expression {

operator: Operator,

left: Box<Expression>,

right: Box<Expression>,

}

Rc

Позволяет нескольким переменным владеть одним объектом размещенным в куче.

Не работающий код.

let a = "Hello, World!".to_string();

let b = a;

let c = a; // Ошибка: use of moved value

Чтобы он заработал, добавим Rc.

let a = Rc::new("Hello, World!".to_string());

let b = Rc::clone(&a);

let c = Rc::clone(&a);

Код также будет работать если мы скопируем объект.

let a = "Hello, World!".to_string();

let b = a.clone();

let c = a;

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

Arc

То же что и Rc, но безопасное для использования в многопоточных приложениях. Это значит, что его можно использовать из разных потоков, не боясь гонок данных.

let a = Arc::new(1);

let b = Arc::clone(&a);

let c = Arc::clone(&a);

Дороже с точки зрения производительности из-за способа подсчёта ссылок.

RefCell

Позволяет изменять данные внутри себя даже если объявлен как неизменяемый.

let a = RefCell::new(1);

*a.borrow_mut() += 1;

dbg!(a); // 2

Комбо

RefCell часто комбинируют с Rc в виде Rc<RefCell<T>>. Это позволяет каждому владельцу ссылки изменять общий объект.

let a = Rc::new(RefCell::new(1));

let b = Rc::clone(&a);

let c = Rc::clone(&a);

*b.borrow_mut() += 1;

dbg!(&a); // 2

dbg!(&c); // Тоже 2

*c.borrow_mut() += 1;

dbg!(&a); // 3

dbg!(&b); // Тоже 3

Заключение

Главное преимущество умных указателей – избегание ошибок типа segfault и выстрелов в ногу, характерных для C и C++, сохраняя при этом удобство использования.

Если статья была полезной, вас могут заинтересовать и другие статьи в моём телеграм-канале.

Показать полностью
[моё] Обучение Rust Программирование C++ Длиннопост
16
Посты не найдены
О нас
О Пикабу Контакты Реклама Сообщить об ошибке Сообщить о нарушении законодательства Отзывы и предложения Новости Пикабу Мобильное приложение RSS
Информация
Помощь Кодекс Пикабу Команда Пикабу Конфиденциальность Правила соцсети О рекомендациях О компании
Наши проекты
Блоги Работа Промокоды Игры Курсы
Партнёры
Промокоды Биг Гик Промокоды Lamoda Промокоды Мвидео Промокоды Яндекс Директ Промокоды Отелло Промокоды Aroma Butik Промокоды Яндекс Путешествия Постила Футбол сегодня
На информационном ресурсе Pikabu.ru применяются рекомендательные технологии