网站不备案有什么后果,网站订单系统模板下载,濮阳网络教育,开发公司工程部绩效考核管理办法✨博客主页何曾参静谧的博客#x1f4cc;文章专栏「C/C」C/C程序设计#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…
✨博客主页何曾参静谧的博客文章专栏「C/C」C/C程序设计全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasolid函数说明「Math」探秘数学世界 目录 C异常处理详解一、C 异常处理的基本结构二、自定义异常类三、异常规范C11 已废弃四、标准异常类五、多重捕获和重新抛出六、总结 C异常处理详解
在现代编程中异常处理是确保程序健壮性和可靠性的重要机制之一。C 提供了一套强大且灵活的异常处理框架允许程序在运行时遇到错误或异常情况时能够优雅地处理这些状况而不是简单地崩溃或终止。本文将深入探讨 C 中的异常处理机制包括 try、throw 和 catch 关键字的使用以及自定义异常类、异常规范、标准异常类和多重捕获等内容。
一、C 异常处理的基本结构
C 的异常处理主要依赖于三个关键字try、throw 和 catch。 try 块 try 块标记了一段可能抛出异常的代码。在 try 块内部你可以写正常的程序代码同时也可以调用可能抛出异常的函数或方法。 try {// 可能抛出异常的代码
}throw 语句 当 try 块中的代码检测到某个错误或异常情况时可以使用 throw 语句抛出一个异常。throw 后面可以跟基本数据类型如 int、char 等、对象或者是指针。 throw expression;例如如果检测到数组越界可以抛出一个整数异常 throw 100; // 抛出一个整数异常catch 块 catch 块用于捕获和处理由 try 块中抛出的异常。每个 catch 块都会指定一个异常类型当抛出的异常类型与 catch 块指定的类型匹配时该 catch 块就会被执行。 catch (exception_type variable) {// 处理异常的代码
}例如捕获并处理前面抛出的整数异常 try {throw 100;
} catch (int e) {std::cout Caught an integer exception: e std::endl;
}二、自定义异常类
在实际开发中常常需要抛出和捕获具有特定意义的异常。为此可以定义自己的异常类。自定义异常类通常继承自 std::exception 类或其派生类这样可以利用标准异常类提供的功能如获取错误消息等。
#include iostream
#include exception
#include stringclass MyException : public std::exception {
public:MyException(const std::string message) : msg_(message) {}virtual const char* what() const noexcept override {return msg_.c_str();}private:std::string msg_;
};int main() {try {throw MyException(Something went wrong!);} catch (const MyException e) {std::cerr Caught MyException: e.what() std::endl;}return 0;
}三、异常规范C11 已废弃
在 C11 之前函数声明中可以包含异常规范指明该函数可能抛出的异常类型。不过由于该特性在实际应用中很少使用且存在限制C11 标准已将其废弃并在 C17 中完全移除。因此这里仅做简要介绍不建议在新代码中使用。
void mightThrowException() throw(int, std::bad_alloc); // C98/03 语法C11 已废弃四、标准异常类
C 标准库提供了一系列标准异常类这些类继承自 std::exception 类。使用标准异常类可以让代码更加规范便于理解和维护。
std::bad_alloc内存分配失败时抛出。std::bad_cast动态类型转换失败时抛出如 dynamic_cast 失败。std::bad_exception未知的异常被 std::unexpected 函数抛出时抛出。std::domain_error数学函数域错误时抛出如 sqrt(-1)。std::invalid_argument传递给函数的参数无效时抛出。std::length_error试图创建超过允许长度的对象时抛出如 std::string 太长。std::out_of_range使用超出有效范围的值时抛出如数组索引越界。std::overflow_error算术运算结果超出可表示范围时抛出如整数溢出。std::range_error使用无效范围的值时抛出如 std::stoi 转换失败。std::runtime_error运行时错误时抛出一般异常。std::underflow_error算术运算结果低于可表示范围时抛出如负整数下溢。
五、多重捕获和重新抛出
一个 try 块可以对应多个 catch 块以捕获不同类型的异常。此外还可以在 catch 块中重新抛出异常以便上层调用者处理。
try {// 可能抛出多种异常的代码
} catch (const std::runtime_error e) {std::cerr Runtime error: e.what() std::endl;
} catch (const std::bad_alloc e) {std::cerr Memory allocation failed: e.what() std::endl;
} catch (...) {std::cerr Unknown exception caught! std::endl;// 可以选择重新抛出异常throw;
}在上面的代码中catch (...) 是一个通配符捕获块它可以捕获所有类型的异常。
六、总结
C 的异常处理机制为编写健壮和可靠的程序提供了强大的支持。通过合理使用 try、throw 和 catch 关键字以及自定义异常类和标准异常类可以显著提升代码的错误处理能力和可维护性。在实际开发中应根据具体需求选择合适的异常处理方式并尽量避免滥用异常以保持代码的清晰和高效。