捕获异常:除以零

新手上路,请多包涵

当我尝试除以 0 时,以下代码未捕获异常。我需要抛出异常,还是计算机在运行时自动抛出异常?

 int i = 0;

cin >> i;  // what if someone enters zero?

try {
    i = 5/i;
}
catch (std::logic_error e) {

    cerr << e.what();
}

原文由 user33424 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 871
2 个回答

您需要自己检查并抛出异常。整数除以零在标准 C++ 中也不例外。

浮点除以零也不是,但至少它有处理它的特定方法。

ISO 标准中列出的例外情况是:

 namespace std {
    class logic_error;
        class domain_error;
        class invalid_argument;
        class length_error;
        class out_of_range;
    class runtime_error;
        class range_error;
        class overflow_error;
        class underflow_error;
}

您可以非常有说服力地争辩说 overflow_error (由 IEEE754 浮点生成的无穷大可能被认为是溢出)或 domain_error (这 输入值的问题)将是理想的表示除以零。

但是, 5.6 (属于 C++11 部分,尽管我认为这与之前的迭代相比没有改变)明确指出:

如果 /% 的第二个操作数为零,则行为未定义。

因此,它 可能会 抛出那些(或任何其他)异常。它还可以格式化您的硬盘并嘲笑:-)


如果你想实现这样的野兽,你可以在下面的程序中使用类似 intDivEx 的东西(使用溢出变体):

 #include <iostream>
#include <stdexcept>

// Integer division/remainder, catching divide by zero.

inline int intDivEx (int numerator, int denominator) {
    if (denominator == 0)
        throw std::overflow_error("Divide by zero exception");
    return numerator / denominator;
}

inline int intModEx (int numerator, int denominator) {
    if (denominator == 0)
        throw std::overflow_error("Divide by zero exception");
    return numerator % denominator;
}

int main (void) {
    int i = 42;

    try { i = intDivEx (10, 0); }
    catch (std::overflow_error &e) {
        std::cout << e.what() << " -> ";
    }
    std::cout << i << std::endl;

    try { i = intDivEx (10, 2); }
    catch (std::overflow_error &e) {
        std::cout << e.what() << " -> ";
    }
    std::cout << i << std::endl;

    return 0;
}

这输出:

 Divide by zero exception -> 42
5

你可以看到它抛出并捕获了除以零的异常(保持返回变量不变)。


% 等效项几乎完全相同:

原文由 paxdiablo 发布,翻译遵循 CC BY-SA 4.0 许可协议

这个如何?用 Clang 测试,GCC 抛出 SIGILL。

 #include <iostream>
#include <cassert>

int main()
{
    unsigned int x = 42;
    unsigned int y = x;
    y -= x;
    x /= y;

    std::cout << x << " != "<< *(&x) << std::endl;
    assert (*(&x) == x);
}

原文由 damkrat 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题