📜  在C ++中处理被零除的异常

📅  最后修改于: 2021-05-31 19:10:07             🧑  作者: Mango

我们使用异常处理来系统地克服程序执行过程中发生的异常。

将数字除以零是一个数学错误(未定义),我们可以使用异常处理来优雅地克服此类操作。如果您在不使用异常处理的情况下编写代码,那么被零除的输出将显示为无穷大,无法进一步处理。

考虑下面给出的代码,除法函数返回分子除以分母的结果,该结果存储在主变量结果中,然后显示。该除法函数对于分母为零没有任何要求。

// Program to show division without using
// Exception Handling
  
#include 
using namespace std;
  
// Defining function Division
float Division(float num, float den)
{
    // return the result of division
    return (num / den);
  
} // end Division
  
int main()
{
    // storing 12.5 in numerator
    // and 0 in denominator
    float numerator = 12.5;
    float denominator = 0;
    float result;
  
    // calls Division function
    result = Division(numerator, denominator);
  
    // display the value stored in result
    cout << "The quotient of 12.5/0 is "
         << result << endl;
  
} // end main
输出:
The quotient of 12.5/0 is inf

我们可以通过多种不同的方式处理此异常,以下列出了其中的一些方式

  • 1)使用runtime_error类

    runtime_error类是标准库类异常的派生类,在异常头文件中定义,用于表示运行时错误。
    现在,我们考虑完全相同的代码,但包括以零可能性处理除法的代码。在这里,我们在main内部有一个try块,它调用Division函数。除法函数检查传递的分母是否等于零(如果否,则返回商),如果是,则抛出runtime_error异常。该异常由catch块捕获,该块打印消息“发生异常”,然后使用runtime_error对象e调用what函数。 what()函数(在下面的代码中使用)是stdexcept头文件中定义的Standard异常类的虚函数,用于标识异常。这将打印消息“数学错误:试图除以零”,此后程序将恢复普通的指令序列。

    // Program to depict how to handle
    // divide by zero exception
      
    #include 
    #include  // To use runtime_error
    using namespace std;
      
    // Defining function Division
    float Division(float num, float den)
    {
        // If denominator is Zero
        // throw runtime_error
        if (den == 0) {
            throw runtime_error("Math error: Attempted to divide by Zero\n");
        }
      
        // Otherwise return the result of division
        return (num / den);
      
    } // end Division
      
    int main()
    {
        float numerator, denominator, result;
        numerator = 12.5;
        denominator = 0;
      
        // try block calls the Division function
        try {
            result = Division(numerator, denominator);
      
            // this will not print in this example
            cout << "The quotient is "
                 << result << endl;
        }
      
        // catch block catches exception thrown
        // by the Division function
        catch (runtime_error& e) {
      
            // prints that exception has occurred
            // calls the what function
            // using runtime_error object
            cout << "Exception occurred" << endl
                 << e.what();
        }
      
    } // end main
    
    输出:
    Exception occurred
    Math error: Attempted to divide by Zero
    
  • 2)使用用户定义的异常处理

    在这里,我们定义了一个Exception类,该类从runtime_error类公开继承。在类Exception的内部,我们仅定义一个构造函数,该构造函数在使用类对象调用时将显示消息“数学错误:试图除以零”。当分母为零时,我们定义除法函数,该函数调用Exception类的构造函数,否则返回商。在main内部,我们给分子和分母分别赋值12.5和0。然后我们进入try块,该块调用Division函数,该函数将返回商或引发异常。 catch块捕获Exception类型的异常,显示消息“发生异常”,然后调用what函数。处理异常后,程序将恢复。

    // Program to depict user defined exception handling
      
    #include 
    #include 
    // For using runtime_error
      
    using namespace std;
      
    // User defined class for handling exception
    // Class Exception publicly inherits
    // the runtime_error class
      
    class Exception : public runtime_error {
    public:
        // Defining constructor of class Exception
        // that passes a string message to the runtime_error class
        Exception()
            : runtime_error("Math error: Attempted to divide by Zero\n")
        {
        }
    };
      
    // defining Division function
    float Division(float num, float den)
    {
      
        // If denominator is Zero
        // throw user defined exception of type Exception
        if (den == 0)
            throw Exception();
      
        // otherwise return the result of division
        return (num / den);
      
    } // end Division
      
    int main()
    {
        float numerator, denominator, result;
        numerator = 12.5;
        denominator = 0;
      
        // try block calls the Division function
        try {
            result = Division(numerator, denominator);
      
            // this will not print in this example
            cout << "The quotient is " << result << endl;
        }
      
        // catch block catches exception if any
        // of type Exception
        catch (Exception& e) {
      
            // prints that exception has occurred
            // calls the what function using object of
            // the user defined class called Exception
            cout << "Exception occurred" << endl
                 << e.what();
        }
      
    } // end main
    
    输出:
    Exception occurred
    Math error: Attempted to divide by Zero
    
  • 3)使用堆栈展开

    在堆栈展开中,我们有一个主要的内部,try块调用Division函数,而Division函数依次调用CheckDenominator函数。 CheckDenominator函数检查分母是否为零,如果为true,则引发异常,否则返回分母的值。除法函数计算商的值(如果传递了分母的非零值)并将其返回给主函数。 catch块捕获抛出的所有异常,并显示消息“发生异常”,并调用显示“ Math error:试图除以零的数学错误”的what函数。此后,程序将恢复。

    // Program to depict Exception Handling
    // Using stack unwinding
      
    #include 
    #include 
    using namespace std;
      
    // defining the CheckDenominator function
    float CheckDenominator(float den)
    {
      
        // if denominator is zero
        // throw exception
        if (den == 0) {
            throw runtime_error("Math error: Attempted to divide by zero\n");
        }
        else
            return den;
    } // end CheckDenominator
      
    // defining Division function
    float Division(float num, float den)
    {
        // Division function calls CheckDenominator
        return (num / CheckDenominator(den));
      
    } // end Division
      
    int main()
    {
        float numerator, denominator, result;
        numerator = 12.5;
        denominator = 0;
      
        // try block calls the Division function
        try {
            result = Division(numerator, denominator);
      
            // This will not print in this example
            cout << "The quotient is "
                 << result << endl;
        }
      
        // catch block catches exception if any
        catch (runtime_error& e) {
      
            // prints that exception has occurred
            // calls the what function using object of
            // runtime_error class
            cout << "Exception occurred" << endl
                 << e.what();
        }
    } // end main
    
    输出:
    Exception occurred
    Math error: Attempted to divide by zero
    
  • 4)使用try and catch(…)

    在此代码中,try块调用CheckDenominator函数。在CheckDenominator函数,我们检查分母是否为零,如果为true,则通过传递字符串“ Error”引发异常。该字符串由catch块捕获,因此输出消息“发生异常”。这里的catch块能够捕获任何类型的异常。

    // Program to depict use of try catch block
      
    #include 
    #include 
    using namespace std;
      
    // defining CheckDenominator
    float CheckDenominator(float den)
    {
        if (den == 0)
            throw "Error";
        else
            return den;
    } // end CheckDenominator
      
    int main()
    {
        float numerator, denominator, result;
        numerator = 12.5;
        denominator = 0;
      
        // try block
        try {
      
            // calls the CheckDenominator function
            // by passing a string "Error"
            if (CheckDenominator(denominator)) {
      
                result = (numerator / denominator);
                cout << "The quotient is "
                     << result << endl;
            }
        }
      
        // catch block
        // capable of catching any type of exception
        catch (...) {
      
            // Display a that exception has occurred
            cout << "Exception occurred" << endl;
        }
      
    } // end main
    
    输出:
    Exception occurred
    
想要从精选的最佳视频中学习并解决问题,请查看有关从基础到高级C++的C++基础课程以及有关语言和STL的C++ STL课程。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”