이 글에서는 C++에서 0으로 나누기(Divide by Zero) 예외를 처리하는 세 가지 방법을 소개합니다.
수학에서 어떤 수를 0으로 나누는 것은 정의되지 않은 연산입니다. 따라서 프로그램을 작성할 때 이러한 상황을 적절히 처리하지 않으면 런타임 오류가 발생하거나 프로그램이 비정상적으로 종료되어 사용자에게 불편을 줄 수 있습니다. C++의 예외 처리 메커니즘인 try, catch, throw를 활용하면 이러한 문제를 안전하게 방지할 수 있습니다.
1. runtime_error 클래스 활용
가장 간단한 방법은 C++ 표준 라이브러리(<stdexcept>)에서 제공하는 runtime_error 클래스를 사용하는 것입니다. 분모가 0인지 검사한 후, 0이라면 throw 문으로 예외를 발생시키고 호출부의 catch 블록에서 이를 처리합니다.
예제 코드
#include <iostream>
#include <stdexcept>
using namespace std;
// 0으로 나누기 예외 처리
float Division(float num, float den) {
if (den == 0) {
throw runtime_error("Math error: Attempted to divide by Zero\n");
}
return (num / den);
}
int main() {
float numerator, denominator, result;
numerator = 12.5;
denominator = 0;
try {
result = Division(numerator, denominator);
cout << "The quotient is " << result << endl;
}
catch (runtime_error& e) {
cout << "Exception occurred" << endl << e.what();
}
}실행 결과
Exception occurred Math error: Attempted to divide by Zero
2. 사용자 정의 예외 클래스 활용
runtime_error를 상속받아 프로젝트에 맞는 사용자 정의 예외 클래스를 만들 수도 있습니다. 이렇게 하면 예외 유형을 명확하게 구분할 수 있어 코드의 가독성과 유지보수성이 크게 향상됩니다.
예제 코드
#include <iostream>
#include <stdexcept>
using namespace std;
// 예외 처리를 위한 사용자 정의 클래스
class Exception : public runtime_error {
public:
Exception()
: runtime_error("Math error: Attempted to divide by Zero\n") {
}
};
float Division(float num, float den) {
if (den == 0)
throw Exception();
return (num / den);
}
int main() {
float numerator, denominator, result;
numerator = 12.5;
denominator = 0;
// try 블록에서 Division 함수 호출
try {
result = Division(numerator, denominator);
cout << "The quotient is " << result << endl;
}
catch (Exception& e) {
cout << "Exception occurred" << endl << e.what();
}
}실행 결과
Exception occurred Math error: Attempted to divide by Zero
3. 스택 풀기(Stack Unwinding) 활용
예외가 발생하면 C++는 해당 예외를 처리할 catch 블록을 찾을 때까지 호출 스택을 거슬러 올라가는데, 이 과정을 스택 풀기(stack unwinding)라고 합니다. 아래 예제처럼 별도의 유효성 검사 함수에서 예외를 던지면, 이를 호출한 상위 함수로 제어 흐름이 자동으로 전달됩니다.
예제 코드
#include <iostream>
#include <stdexcept>
using namespace std;
// 예외를 처리하는 함수 정의
float CheckDenominator(float den) {
if (den == 0) {
throw runtime_error("Math error: Attempted to divide by zero\n");
}
else
return den;
}
float Division(float num, float den) {
return (num / CheckDenominator(den));
}
int main() {
float numerator, denominator, result;
numerator = 12.5;
denominator = 0;
try {
result = Division(numerator, denominator);
cout << "The quotient is " << result << endl;
}
catch (runtime_error& e) {
cout << "Exception occurred" << endl << e.what();
}
}실행 결과
Exception occurred Math error: Attempted to divide by zero
마무리
지금까지 C++에서 0으로 나누기 예외를 처리하는 세 가지 방법을 살펴보았습니다.
- runtime_error 클래스: 표준 라이브러리를 활용한 가장 간단한 방법
- 사용자 정의 예외 클래스: runtime_error를 상속해 예외를 체계적으로 관리
- 스택 풀기: 호출 스택을 통해 상위 함수로 예외를 자동 전달
실무에서는 프로그램의 구조와 요구 사항에 맞는 방법을 선택해 사용자에게 친절한 오류 메시지를 제공하고, 프로그램의 안정성을 확보하는 것이 중요합니다.