[C++]/C++ 언어 기초
32. [C++] 예외처리
JuJu(INTJ)
2024. 4. 25. 10:30
🍀 예외처리 방법
#1. if-else문 사용
#include "stdafx.h"
#include <iostream>
using namespace std;
int main(void)
{
int num1, num2;
cout<<"두 개의 숫자 입력: ";
cin>>num1>>num2;
if(num2 == 0){
cout<<"나누는 수는 0이 될 수 없습니다.\n프로그램을 다시 실행해주세요."<<endl;
}else{
cout<<"나눗셈의 몫: "<< num1/num2<<endl;
cout<<"나눗셈의 나머지: "<<num1%num2<<endl;
}
return 0;
}
- 단점 : 프로그램 흐름을 구성하는 코드와 예외처리 코드를 구분하기 힘들다.
#2. try - catch문 사용
#include <iostream>
using namespace std;
int main(void)
{
int num1, num2;
cout<<"두 개의 숫자 입력: ";
cin>>num1>>num2;
try{
if(num2 == 0)
throw num2;
cout<<"나눗셈의 몫: "<< num1/num2<<endl;
cout<<"나눗셈의 나머지: "<<num1%num2<<endl;
}
catch(int expn){
cout<<"나누는 수는 0이 될 수 없습니다.\n프로그램을 다시 실행해주세요."<<endl;
}
return 0;
}
🍀 try, catch문의 사용 방법
- try 예외를 발견한다
- catch 예외를 잡는다
- throw 예외를 던진다
try 블록
- 예외발생에 대한 검사의 범위를 지정함. try 내에서 예외가 발생하면 예외처리 매커니즘을 발생
try{
//예외발생 예상지역
}
catch 블록
- 예외를 발견했을 때, 처리하는 부분
catch(처리할 예외 명시){
//예외 처리
}
throw 블록
- expn에는 변수, 상수, 객체 등 모든 데이터가 들어갈 수 있다
throw expn;
- try, catch문은 하나의 문장이므로 항상 이어서 등장해야한다.
- 예외가 발생하게되면 예외 발생 지역 이후가 아닌 catch 블록 이후가 실행된다.
- 하나의 try문에 여러개의 catch문을 사용할 수 있다.
- try에서 검사 범위를 지정하고 throw로 검사 조건을 설정해준 후 catch로 던져주면 catch에서 예외를 처리한다.
🍀 Stack Unwinding(스택 풀기)
#include "stdafx.h"
#include <iostream>
using namespace std;
void Divide(int num1, int num2)
{
if(num2 == 0)
throw num2; //try문 안에 존재하지 않기 때문에 함수 호출 부분으로 예외 값과 함께 넘겨줌
cout<<"나눗셈의 몫: "<< num1/num2<<endl;
cout<<"나눗셈의 나머지: "<<num1%num2<<endl;
}
int main(void)
{
int num1, num2;
cout<<"두 개의 숫자 입력: ";
cin>>num1>>num2;
try{
Divide(num1, num2); //이 부분으로 예외처리 권한과 값을 넘겨줌
cout<<"나눗셈을 마쳤습니다."<<endl;
}
catch(int e){
cout<<"나누는 수는 0이 될 수 없습니다.\n프로그램을 다시 실행해주세요."<<endl;
}
return 0;
}
#include "stdafx.h"
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
int StoI(char * str){
int len = strlen(str);
int num = 0;
for(int i = 0 ; i < len ; i ++){
if(str[i] < '0' || str[i] > '9')
throw str[i];
num += (int)(pow((double)10, (len-1)-i) * (str[i] + (7 - '7')));
}
return num;
}
int main(void){
char str1[100];
char str2[200];
while(1){
cout << "두 개의 숫자 입력: ";
cin >> str1 >> str2;
try{
cout << str1 << " + " << str2 << " = " << StoI(str1) + StoI(str2) << endl;
break;
} catch(char ch){
cout << "문자: " << ch << "가 입력되었습니다." << endl;
cout << "재입력 진행합니다." << endl << endl;
}
}
cout << "프로그램을 종료합니다." << endl;
return 0;
}
- 함수를 호출하고, 함수 로직을 돌고 있을 때 throw문에서 예외가 발생하면, 예외처리 데이터와 책임은 함수 호출 시점으로 넘어가게 된다.
- 함수 내에서 함수를 호출한 영역으로 예외 데이터를 종료되면, 해당 함수는 종료된다.
🍀 스택 풀기
#include "stdafx.h"
#include <iostream>
using namespace std;
void SimpleFuncOne(void);
void SimpleFuncTwo(void);
void SimpleFuncThree(void);
int main(void){
try{
SimpleFuncOne();
}
catch(int expn){
cout << "예외코드: " << expn << endl;
}
return 0;
}
void SimpleFuncOne(void){
cout << "SimpleFuncOne(void)" << endl;
SimpleFuncTwo();
}
void SimpleFuncTwo(void){
cout << "SimpleFuncTwo(void)" << endl;
SimpleFuncThree();
}
void SimpleFuncThree(void){
cout << "SimpleFuncThree(void)" << endl;
throw -1;
}
- 스택풀기란 예외가 처리되지 않아서 함수를 호출한 영역으로 예외 데이터가 전달되는 현상
- 위 코드에서 실행 순서는 main -> SimpleFuncOne -> SimpleFuncTwo -> SimpleFuncThree이다.
- 이후 SimpleFuncThree에서 예외가 발생했기 때문에 예외 처리 순서는 SimpleFuncThree -> SimpleFuncTwo -> SimpleFuncOne -> main이 된다.
- 함수 호출 스택이 쌓이고 예외 데이터가 전달되면서 스택을 해제하기 때문에 스택 풀기라는 이름이 생긴 것이다.
반응형