### **Задача 1: Обработка деления на ноль**

**Описание:** Напишите программу, которая запрашивает два числа и делит первое на второе. Обработайте ситуацию, если второе число равно нулю.

#include <iostream>

int main() {
    double a, b;
    std::cout << "Введите два числа: ";
    std::cin >> a >> b;

    // код здесь
    return 0;
}


---

### **Задача 2: Обработка неправильного индекса массива**

**Описание:** Напишите программу, которая обращается к элементу массива по индексу. Обработайте выход за границы массива.

#include <iostream>

int main() {
    int arr[] = {10, 20, 30};
    int size = 3;
    int index;
    std::cout << "Введите индекс (0-2): ";
    std::cin >> index;

    // код здесь

    return 0;
}


---

### **Задача 3: Использование стандартного исключения `std::out_of_range`**

**Описание:** Используйте `std::vector` и вызовите `at()` с неправильным индексом. Обработайте исключение `std::out_of_range`.

#include <iostream>
#include <vector>
#include <stdexcept>

int main() {
    std::vector<int> vec = {1, 2, 3};
    int index;
    std::cout << "Введите индекс: ";
    std::cin >> index;

    // код здесь
	return 0;
}


---

### **Задача 4: Генерация исключения в функции**

**Описание:** Напишите функцию, которая принимает строку и возвращает её длину. Если строка пустая, функция генерирует исключение.

#include <iostream>
#include <stdexcept>
#include <string>

int getStringLength(const std::string& str) {
    if (str.empty()) {
        throw std::invalid_argument("String is empty!");
    }
    return static_cast<int>(str.length());
}

int main() {
    std::string input;
    std::cout << "Введите строку: ";
    std::getline(std::cin, input);

    // код здесь
    return 0;
}


---

### **Задача 5: Кастомный класс исключения**

**Описание:** Создайте свой класс исключения, унаследованный от `std::exception`, и используйте его в программе.

#include <iostream>
#include <exception>
#include <string>

class MyException : public std::exception {
    std::string msg;
public:
    MyException(const std::string& message) : msg(message) {}
    const char* what() const noexcept override {
        return msg.c_str();
    }
};

int main() {
    try {
        throw MyException("Произошло пользовательское исключение!");
    } catch (const MyException& e) {
        std::cerr << "Ошибка: " << e.what() << std::endl;
    }
    return 0;
}

---

### **Задача 6: Обработка нескольких типов исключений**

**Описание:** Напишите программу, которая может выбросить разные типы исключений. Обработайте их по-разному.

#include <iostream>
#include <stdexcept>

int main() {
    int choice;
    std::cout << "Введите 1 для std::runtime_error, 2 для std::invalid_argument: ";
    std::cin >> choice;

    try {
        if (choice == 1) {
            throw std::runtime_error("Runtime error occurred!");
        } else if (choice == 2) {
            throw std::invalid_argument("Invalid argument!");
        } else {
            throw 42; // произвольное исключение
        }
    } catch (const std::runtime_error& e) {
        std::cerr << "Runtime Error: " << e.what() << std::endl;
    } catch (const std::invalid_argument& e) {
        std::cerr << "Invalid Argument: " << e.what() << std::endl;
    } catch (...) {
        std::cerr << "Неизвестная ошибка." << std::endl;
    }
    return 0;
}

---

### **Задача 7: Использование `using namespace`**

**Описание:** Объявите пространство имён `Geometry` с константой `PI` и функцией `area_circle`. Используйте `using namespace` для упрощения доступа.

#include <iostream>

    const double PI = 3.14159;
    double area_circle(double r) {
        return PI * r * r;
    }

int main() {
    double radius = 5.0;
    std::cout << "Площадь круга: " << area_circle(radius) << std::endl;
    return 0;
}

---

### **Задача 8: Использование `using` для конкретного имени**

**Описание:** Используйте `using` для импорта только функции `area_circle` из пространства имён `Geometry`.

#include <iostream>

namespace Geometry {
    const double PI = 3.14159;
    double area_circle(double r) {
        return PI * r * r;
    }
}

int main() {
    double radius = 5.0;
    std::cout << "Площадь круга: " << area_circle(radius) << std::endl;
    return 0;
}

---

### **Задача 9: Вложенные пространства имён**

**Описание:** Создайте вложенное пространство имён `Graphics::Shapes` с функцией `draw_circle`. Обратитесь к ней из `main`.

#include <iostream>

        void draw_circle() {
            std::cout << "Рисуем круг." << std::endl;
        }


int main() {
    draw_circle();
    return 0;
}

---

### **Задача 10: Анонимное (безымянное) пространство имён**

**Описание:** Создайте переменную и функцию в анонимном пространстве имён. Покажите, что они доступны только в этом файле.

#include <iostream>


    int secret_value = 100;
    void print_secret() {
        std::cout << "Секретное значение: " << secret_value << std::endl;
    }

int main() {
    print_secret();
    return 0;
}
```

---

### **Задача 11: Обработка исключения при открытии файла**

**Описание:** Попробуйте открыть файл с помощью `std::ifstream`. Обработайте ситуацию, если файл не найден.

#include <iostream>
#include <fstream>
#include <stdexcept>

int main() {
    std::ifstream file("nonexistent.txt");

    try {
        if (!file.is_open()) {
            throw std::runtime_error("Не удалось открыть файл.");
        }
        // Читаем файл...
        file.close();
    } catch (const std::runtime_error& e) {
        std::cerr << "Ошибка: " << e.what() << std::endl;
    }
    return 0;
}

---

### **Задача 12: Перехват всех исключений с `catch(...)`**

**Описание:** Напишите программу, которая может выбросить любое исключение. Используйте `catch(...)` для его перехвата.

#include <iostream>

int main() {
    try {
        throw 3.14; // может быть любое исключение
    } catch (...) {
        std::cerr << "Перехвачено неизвестное исключение." << std::endl;
    }
    return 0;
}

---

### **Задача 13: Повторное объявление пространства имён**

**Описание:** Объявите пространство имён `Utils` в двух разных блоках. Покажите, что все элементы объединяются.

#include <iostream>


    void helper1() {
        std::cout << "Helper 1" << std::endl;
    }



    void helper2() {
        std::cout << "Helper 2" << std::endl;
    }

int main() {
    Utils::helper1();
    Utils::helper2();
    return 0;
}

---

### **Задача 14: Обработка исключения при конвертации строки в число**

**Описание:** Используйте `std::stoi` для преобразования строки в число. Обработайте исключение `std::invalid_argument`, если строка некорректна.

#include <iostream>
#include <string>
#include <stdexcept>

int main() {
    std::string input = "abc"; // строка не является числом

   // код здесь
    return 0;
}
```

---

### **Задача 15: Использование `noexcept` и `throw`**

**Описание:** Напишите функцию с `noexcept`, которая не должна выбрасывать исключений. Попробуйте выбросить исключение и посмотрите результат.

#include <iostream>

void safe_function() noexcept {
    // throw std::runtime_error("Это вызовет std::terminate!"); // Не рекомендуется
    std::cout << "Функция выполнена безопасно." << std::endl;
}

int main() {
    safe_function();
    return 0;
}

---

### **Задача 16: Пространство имён с классом и методом, выбрасывающим исключение**

**Описание:** Создайте класс в пространстве имён, метод которого может выбросить исключение.

#include <iostream>
#include <stdexcept>

namespace Game {
    class Player {
    public:
        int health = 100;
        void takeDamage(int damage) {
            if (damage > health) {
                throw std::runtime_error("Игрок убит!");
            }
            health -= damage;
        }
    };
}

int main() {
    Game::Player p;
    try {
        p.takeDamage(120);
    } catch (const std::runtime_error& e) {
        std::cerr << "Ошибка: " << e.what() << std::endl;
    }
    return 0;
}

---

### **Задача 17: Обработка исключения при делении в функции с возвратом результата**

**Описание:** Напишите функцию, возвращающую результат деления. Обработайте деление на ноль внутри функции.

#include <iostream>
#include <stdexcept>

double divide(double a, double b) {
    if (b == 0) {
        throw std::invalid_argument("Деление на ноль в функции divide.");
    }
    return a / b;
}

int main() {
    try {
        double result = divide(10.0, 0.0);
        std::cout << "Результат: " << result << std::endl;
    } catch (const std::invalid_argument& e) {
        std::cerr << "Ошибка: " << e.what() << std::endl;
    }
    return 0;
}

---

### **Задача 18: Пространство имён с `using` внутри функции**

**Описание:** Используйте `using` внутри функции, чтобы избежать конфликта имён в глобальной области.

#include <iostream>

namespace A {
    int value = 10;
}

namespace B {
    int value = 20;
}

void printValues() {
    using A::value; // value теперь A::value
    std::cout << "A::value: " << value << std::endl;
    std::cout << "B::value: " << B::value << std::endl; // полный путь
}

int main() {
    printValues();
    return 0;
}

---

### **Задача 19: Обработка исключения при выделении памяти**

**Описание:** Попробуйте выделить слишком большой объём памяти. Обработайте исключение `std::bad_alloc`.

#include <iostream>
#include <new>

int main() {
    try {
        // Попытка выделить огромный объём памяти
        size_t size = static_cast<size_t>(-1); // максимально возможный размер
        int* arr = new int[size];
        delete[] arr;
    } catch (const std::bad_alloc& e) {
        std::cerr << "Ошибка выделения памяти: " << e.what() << std::endl;
    }
    return 0;
}

---

### **Задача 20: Комбинирование пространства имён и исключений в классе**

**Описание:** Создайте класс в пространстве имён, который управляет балансом счёта. Метод `withdraw` должен выбрасывать исключение при попытке снять больше, чем есть на счёте.

#include <iostream>
#include <stdexcept>

namespace Banking {
    class Account {
        double balance;
    public:
        Account(double initial) : balance(initial) {}

        void withdraw(double amount) {
            if (amount > balance) {
                throw std::runtime_error("Недостаточно средств на счёте.");
            }
            balance -= amount;
        }

        double getBalance() const {
            return balance;
        }
    };
}

int main() {
    Banking::Account acc(100.0);

    try {
        acc.withdraw(150.0);
    } catch (const std::runtime_error& e) {
        std::cerr << "Ошибка: " << e.what() << std::endl;
    }

    std::cout << "Баланс: " << acc.getBalance() << std::endl;
    return 0;
}