捕捉exception:除以零
当我尝试除以0时,以下代码不会捕获exception。我是否需要抛出exception,或者计算机在运行时是否自动抛出一个exception?
int i = 0; cin >> i; // what if someone enters zero? try { i = 5/i; } catch (std::logic_error e) { cerr << e.what(); } 你需要自己检查并抛出exception。 标准C ++中整数除零不是一个例外。
浮点除以零也不是,但至less具有处理它的具体手段。
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对于用零来表示除法是理想的。 
 但是第5.6节( C++11 ,虽然我认为这与之前的迭代没有什么不同)具体说明: 
如果
/或%的第二个操作数是零,则行为是未定义的。
所以,它可能会抛出(或其他)exception。 它也可以格式化你的硬盘,嘲笑嘲笑:-)
 如果你想实现这样一个野兽,你可以在下面的程序中使用像intDivEx : 
 #include <iostream> #include <stdexcept> // Integer division, 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; } int main (void) { int i = 42; try { i = intDivEx (10, 2); } catch (std::overflow_error e) { std::cout << e.what() << " -> "; } std::cout << i << std::endl; try { i = intDivEx (10, 0); } catch (std::overflow_error e) { std::cout << e.what() << " -> "; } std::cout << i << std::endl; return 0; } 
这输出:
 5 Divide by zero exception -> 5 
你可以看到它抛出并捕获除以零情况的例外。
 相当的%几乎是完全一样的: 
 // Integer remainder, catching divide by zero. inline int intModEx (int numerator, int denominator) { if (denominator == 0) throw std::overflow_error("Divide by zero exception"); return numerator % denominator; } 
更新了ExcessPhase的评论
海湾合作委员会(至less4.8版本)将让你模仿这种行为:
 #include <signal.h> #include <memory> int main() { std::shared_ptr<void(int)> handler( signal(SIGFPE, [](int signum) {throw std::logic_error("FPE"); }), [](__sighandler_t f) { signal(SIGFPE, f); }); int i = 0; cin >> i; // what if someone enters zero? try { i = 5/i; } catch (std::logic_error e) { std::cerr << e.what(); } } 
 这将设置一个新的信号处理程序,它引发一个exception,并将一个shared_ptr传递给旧的信号处理程序,并具有一个自定义的“删除”function,在旧的处理程序超出范围时恢复它。 
您至less需要编译这些选项:
 g++ -c Foo.cc -o Foo.o -fnon-call-exceptions -std=c++11 
Visual C ++也会让你做类似的事情:
 #include <eh.h> #include <memory> int main() { std::shared_ptr<void(unsigned, EXCEPTION_POINTERS*)> handler( _set_se_translator([](unsigned u, EXCEPTION_POINTERS* p) { switch(u) { case FLT_DIVIDE_BY_ZERO: throw std::logic_error("Divide by zero"); ... default: throw std::logic_error("SEH exception"); } }), [](_se_translator_function f) { _set_se_translator(f); }); int i = 0; try { i = 5 / i; } catch(std::logic_error e) { std::cerr << e.what(); } } 
当然,你也可以跳过所有的C ++ 11,把它们放在一个传统的RAIIpipe理结构中。
据我所知,C ++规范没有提到任何有关被零除的除法。 我相信你需要自己动手
Stroustrup在“C ++的devise与发展”(Addison Wesley,1994)中指出,“低级事件,比如算术溢出和零除,被认为是由专门的低层机制来处理,而不是由exception。这使得C ++能够在算术时与其他语言的行为相匹配,同时也避免了在大量stream水线架构上出现的问题,例如被零除的事件是asynchronous的。
 你应该检查,如果i = 0而不是那么分开。 
(可选的,在检查之后,你可以抛出exception并在以后处理)。
更多信息: http : //www.cprogramming.com/tutorial/exceptions.html
 您需要使用throw关键字手动throwexception。 
例:
 #include <iostream> using namespace std; double division(int a, int b) { if( b == 0 ) { throw "Division by zero condition!"; } return (a/b); } int main () { int x = 50; int y = 0; double z = 0; try { z = division(x, y); cout << z << endl; }catch (const char* msg) { cerr << msg << endl; } return 0; } 
 do i need to throw an exception or does the computer automatically throws one at runtime? 
 要么你需要throwexception,并catch它。 例如 
 try { //... throw int(); } catch(int i) { } 
 或者catch你的代码抛出的exception。 
 try { int *p = new int(); } catch (std::bad_alloc e) { cerr << e.what(); } 
在你的情况下,我不知道是否有任何标准的例外,除以零。 如果没有这样的例外,那么你可以使用,
 catch(...) { // catch 'any' exception } 
 你可以做assert(2 * i != i) ,它会抛出一个断言。 你可以写你自己的exception类,如果你需要更奇特的东西。