C++语言学习(10):《C++程序设计原理与实践》第五章笔记
第五章是「错误」,探讨了错误类型、错误来源、规避或解决方法(调试)。
错误的分类
- 编译时错误
- 链接时错误
- 运行时错误
- 逻辑错误
错误的来源
找到错误的源头,然后去消除或解决错误;而不是从报错现场,逐层往前排查。
参数检查的位置
如果是由调用者检查,存在的问题:
- 同一个函数被调用多次时,每一处调用者都需要做检查
- 调用者需要知晓被调用函数的实现细节,才能做检查
- 一旦函数的实现改变,所有的调用者的参数检查,都需要修改,维护成本不可控制
- 如果现有的参数检查需要做调整,每一处调用是否都要调整?维护成本不可控制
举例:
在调用处做参数检查(低效、几乎不可维护的修改方式):
正确的做法:函数实现内部做检查:
基于 Exception 的处理方式:
class Bad_area{};
int area(int length, int width)
{
if (length <= 0 || width <= 0)
throw Bad_area();
return length * width;
}
void test_area()
{
int x = -1;
int y = 2;
int z = area(x, y);
std::cout << z << std::endl;
}
在 macOS 上:
在 Linux-x64 上也有类似输出。
但在 MSVC 上,不那么直观,报错是 -1073740791 (0xc0000409).
捕获 Exception
抛出Exception并不够用,还需要捕获。一旦捕获,程序就不会crash,而是继续执行。
劳累,是出现错误的一个原因
逻辑错误 - 浮点数初始值
调试是乏味、费时的
尽量在设计和编码阶段,做仔细点,从而减少出错的情况:
实用调试技术
- 使用基于 Exception 的错误处理
- 一些 clean code 的风格
- 注释要简单有效;能用代码表达清楚的不应该写注释
- 名字要有意义
- 一致的代码层次结构
- 代码应该分成许多小函数,每个函数表达一个逻辑功能
- 避免使用复杂的程序语句
- 在可能的情况下,使用标准库而不是自己的代码
混乱的代码容易隐藏错误
代码混乱,带来的风险是:一旦需要debug,debug的耗时会很多。代码如果工整,可以改善。
编写前置条件,可以提升程序质量
执行了参数的检查;即使是注释形式。
适当编写后置条件
个人认为这些内容,其实可以放在单元测试里。
总结
这一章作者的确给出了很多面向实际C++工程的指导,包括错误处理(推荐用Exception方式)、调试方法, 也掺杂了 clean code 方面的很多细则建议。
个人看下来最实用的是基于 exception 的报错处理:示例代码:
#include <stdexcept>
void error(const std::string& s)
{
throw runtime_error(s);
}
void test_try_catch_error()
{
try {
int x = -1;
int y = 2;
int z = area(x, y);
std::cout << z << std::endl;
}
catch (std::runtime_error& e)
{
std::cerr << "runtime error: " << e.what() << "\n";
return;
}
catch (std::exception& e)
{
std::cerr << "exception: " << e.what() << '\n';
return;
}
catch (...) { // 捕获所有其他类型的异常
std::cerr << "An unknown exception occurred\n";
return;
}
}
调试方法,没有明确的答案,需要结合问题来给出;但是可以明确的是,调试程序的关键在于:我是否知道程序是否运行正确呢?
原文地址:https://blog.csdn.net/baiyu33/article/details/142703205
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!