[C++ Programming] Chapters 5 : Errors
🏫Chapters 5 : Errors
📖Errors
“코딩 뿐만 아니라 인생에 있어서 내가 한 실수를 바로잡는 데에 가장 많은 시간을 보냈다”
-Maurice Wilkes, 1949
📖Your Program
-
우리들의 코드는 모든 정상적인 인풋에 대해 정상적인 아웃풋을 리턴해야 한다.
-
우리들의 코드에 기대하지 않은 인풋(비정상적 인풋)이 얼마든지 들어올 수 있다.
-
하드웨어가 오동작 할 가능성이 있다.
-
운영체제에 오류가 있을 가능성이 있다.
📖Sources of errors
- 왜 에러가 발생하는 가
- 프로그램 문제가 명확하지 않은 경우
- 내가 코딩을 잘못한 경우
- 인풋이 비정상인 경우
📖Kinds of Errors
- 컴파일 에러
- 문법 오류
- 형 오류
- 링크 에러
- 정의가 없는 경우
-
컴파일/링크 에러는 배포되기 전 오직 개발자만 볼 수 있고, 에러메세지가 친절하므로 가장 쉬운 에러
- 런타임 에러
- 잘 돌아가다가 발생하는 에러
- 난이도가 높다
- 로직 에러
- 프로그램이 죽지도 않고 잘 돌아가는데 엉뚱한 아웃풋을 내는 경우
- 수정하기도 어렵고 큰 피해의 가능성도 있는,,
📖Bad function arguments
- 정상적이지 않은, 기대하지 않은 input에 대한 고려를 충분히 해야한다.
- 사람들은 내가 원하는대로만 움직이지 않는다.
📖How to report an error
- 오류에 대한 철학
C “내가 처리해야 할 정상적인 과정 중 하나”
C++ “문법적으로 두 가지 경우(문제상황과 오류상황)을 분류” -
예를 들면, 편의점에서 알바하다가 강도가 칼을 들고 들어와 100만원을 요구하는 상황에서 C는 “죄송합니다, 100만원이 없습니다” 라고 틀리지는 않은 대답을 돌려주는 것과 같다. 겉으로 봐서는 정상인지 아닌지 모른다. 의미를 분석하는 것과 거리가 멀다.
C++은 이러한 대처방법을 비효율적으로 보고 에러 처리에 대한 문법을 새로 만든 것이다. -
에러에 대처하는 예시 코드
- C
int errno = 0; // used to indicate errors int area(int length, int width) { if (length<=0 || width<=0) errno = 7; // || means or return length*width; }
- C++
int z = area(x,y); if (errno==7) error("bad area computation"); // ...
📖Exceptions
-
예제
#include<iostream> using namespace std; class myerror {}; int div(int a, int b){ return a / b; } int main(){ int ans = div(1, 0); // 컴파일 에러는 뜨지 않음. 그러나 런타임에러 (ERROR : divided by 0) cout << ans; return 0; }
-
C 스타일
int div(int a, int b){ if(b == 0){ return -9999; } else return a / b; }
- 코드에 대해 충분히 알지 못하고 있다면
-9999
의 의미를 모르고 정상처리로 생각하게 된다. - 즉, 문법적으로 정상적인 플로우와 비정상적인 플로우를 구분하지 못한다.
- 코드에 대해 충분히 알지 못하고 있다면
-
C++ 스타일
int div(int a, int b){ if(b == 0){ throw myerror(); } else return a / b; } int main(){ int ans = div(1, 0); cout << ans; try{ int ans = div(1, 0); cout << ans; } catch(myerror e){ cout << "my error"; } return 0; }
- 이런 경우 정상종료 된다. 문제상황에 대해 처리를 실행한 뒤 종료된다.
💻실습
-
📝문제 설명 (실습 9)
정수 배열 array와 정수 n이 매개변수로 주어질 때, array에 들어있는 정수 중 n과 가장 가까운 수를 return 하도록 solution 함수를 완성해주세요. -
⚠️제한사항
- 1 ≤ array의 길이 ≤ 100
- 1 ≤ array의 원소 ≤ 100
- 1 ≤ n ≤ 100
- 가장 가까운 수가 여러 개일 경우 더 작은 수를 return 합니다.
#include <string>
#include <vector>
using namespace std;
////////////// My solution //////////////
int solution(vector<int> array, int n) {
int answer = 0;
// 차이로 풀기
int difference;
vector<int> differ;
// 각 배열의 차이를 담은 벡터
for(int i=0; i<array.size(); i++){
difference = n - array[i];
differ.push_back(difference);
}
// -있으면 +로 바꿔주기
for(int i=0;i<differ.size();i++){
if(differ[i]<0){
differ[i] = -differ[i];
}
}
// 가장 작은 differ 값 구하기
int min = 100;
for(int i=0;i<differ.size();i++){
if(differ[i] < min){
min = differ[i];
}
}
// 가장 작은 array 값 구하기
int min_arr = 100;
for(int i=0;i<differ.size();i++){
if(differ[i] == min){
if(array[i] < min_arr){
min_arr = array[i];
}
}
}
answer = min_arr;
return answer;
}
/////////// Professor Solution ///////////
int getDiff(int n, int m);
int solution(vector<int> array, int n){
int answer = -200;
for(int i = 0; i < array.size(); i++){
if(getDiff(array[i], n) < getDiff(answer, n)
|| ((getDiff(array[i], n) == getDiff(answer, n)) && (answer > array[i]))){
answer = array[i];
}
}
return answer;
}
int getDiff(int n, int m){
if(n > m){
return n-m;
}
else
return m-n;
}
-
📝문제 설명 (실습 10)
머쓱이는 프로그래머스에 로그인하려고 합니다.
머쓱이가 입력한 아이디와 패스워드가 담긴 배열id_pw
와 회원들의 정보가 담긴 2차원 배열db
가 주어질 때, 다음과 같이 로그인 성공,
실패에 따른 메시지를 return하도록 solution 함수를 완성해주세요.아이디와 비밀번호가 모두 일치하는 회원정보가 있으면
"login"
을 return합니다.
로그인이 실패했을 때 아이디가 일치하는 회원이 없다면“fail”
를, 아이디는 일치하지만 비밀번호가 일치하는 회원이 없다면“wrong pw”
를 return 합니다.
#include <string>
#include <vector>
using namespace std;
string solution(vector<string> id_pw, vector<vector<string>> db) {
for(int i=0;i<db.size();i++){
if(id_pw[0] == db[i][0]){
if(id_pw[1] == db[i][1])
return "login";
else return "wrong pw";
}
}
return "fail";
}