[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이 된다.
  • 함수 호출 스택이 쌓이고 예외 데이터가 전달되면서 스택을 해제하기 때문에 스택 풀기라는 이름이 생긴 것이다.

 

 

 

 

 

 

 

반응형