제6장 제어(Control) 6.1 구조적 프로그래밍(Structured Programming) 6.2 예외(Exceptions) Reading Chap. 7 ©숙대 창병모
6.1 구조적 프로그래밍 ©숙대 창병모
Fortran 제어 구조 Similar structure may occur in assembly code 10 IF (X .GT. 0.000001) GO TO 20 11 X = -X IF (X .LT. 0.000001) GO TO 50 20 IF (X*Y .LT. 0.00001) GO TO 30 X = X-Y-Y 30 X = X+Y ... 50 CONTINUE X = A Y = B-A GO TO 11 … Similar structure may occur in assembly code ©숙대 창병모
역사적 논쟁 Dijkstra, Goto Statement Considered Harmful Letter to Editor, C ACM, March 1968 Knuth, Structured Prog. with go to Statements You can use goto, but do so in structured way … Continued discussion Welch, “GOTO (Considered Harmful)n, n is Odd” General questions Do syntactic rules force good programming style? Can they help? ©숙대 창병모
구조적 프로그래밍 Standard constructs that structure jumps 언어 S 시작과 끝나는 지점이 일정하다. 언어 S if E then S else S while E do S let t x = E in S end fun t f(t x) : S … Modern programming style Group code in logical blocks Avoid explicit jumps except for function return Cannot jump into middle of block or function body ©숙대 창병모
Expression vs. Statement Expression E Statement S if expression vs. if statement if E then S else S e1 ? e2 : e3 ©숙대 창병모
Syntactic sugar do S while (E) for (e1; e2; e3) S switch (E) { case a : S; …; break; case b : S; …; break; case c : S; …; break; } ©숙대 창병모
6.2 예외(Exceptions) ©숙대 창병모
예외(Exception) 예외 (상황) 예외에 대한 적절한 처리 필요한 예외 관련 구문 심각하지 않은 에러 혹은 비정상적 상황 예외 발생 시 계속 수행할 수 있도록 처리해야 한다 발생된 예외를 처리하지 못하면 프로그램 종료 예외에 대한 적절한 처리 안전한 프로그램 실행을 위해 매우 중요하다. 따라서 최신 언어들은 예외 관련 기능을 제공한다. Java, C++, Standard ML, … 필요한 예외 관련 구문 raise or throw exception(예외 발생)을 위한 식 혹은 문장 Exception handler(예외 처리)를 위한 문장 ©숙대 창병모
언어 S의 예외 S … 언어 S에 예외 추가 throw E try S catch (int x) S 예외 발생 및 예외 처리 기능 S … | throw E | try S catch (int x) S throw E 예외를 발생시킨다. E의 값은 예외의 종류를 나타낸다. 발생된 예외를 처리하지 못하면 프로그램은 종료한다. try S catch (int x) S try 블록에서 예외가 발생하면 잡아서 처리한다. 예외가 발생하지 않으면 다음 문장을 실행 ©숙대 창병모
예외 예제 Factorial1 Factorial2 let int x=0, int y=1 in read x; if x < 0 then throw -1 else while x != 0 do (y = y * x; x = x - 1); print y end Factorial2 let int x=0, int y=1 in read x; try if x < 0 then throw -1 else ( while x != 0 do (y = y * x; x = x - 1); print y ) catch (int e) print e end ©숙대 창병모
실습 #5 언어 S에 예외 처리 기능을 추가하고 이를 인터프리터에서 구현한다. 구현 문법 S … | throw E | try S catch (int x) S 구현 try 블록 내에서 throw 문에 의해 예외가 발생하면 그 이후 문장은 catch 절을 만날 때까지 skip 한다. How ? catch 절에서 예외 처리 후에는 정상적으로 진행한다. try 블록 없이 throw 한 경우는 ? ©숙대 창병모
Java에서 예외 선언 자바에서 예외 타입은 클래스로 선언 예외타입은 클래스이다 Exception 클래스나 서브클래스로부터 상속 받아 정의한다. 예외타입은 클래스이다 생성자, 멤버 필드, 메소드 등을 가질 수 있다. Exception object is a first-class object 일반 object처럼 클래스를 이용하여 정의되고 일반 object처럼 사용될 수 있다. 일반 object와 차이점 : throw 될 수 있다. ©숙대 창병모
예외 클래스 계층 구조 checked exceptions Object Throwable Exception Error User-defined exception classes Runtime Exception Unchecked exceptions ArithmeticException NagativeArraySizeException ArrayIndexOutOfBoundsException SecurityException … ©숙대 창병모
Java 예외 클래스 예 … ArithmeticException ArrayIndexOutofBoundsException 0으로 나누는 경우에 주로 발생하는 예외 상황 RuntimeException으로부터 상속받은 예외 클래스 ArrayIndexOutofBoundsException 배열의 크기보다 큰 원소를 접근하려고 할 때 발생되는 예외 NegativeArraySizeException 배열의 크기가 음수로 된 경우에 발생하는 예외 NullPointerException 생성되지 않은 객체를 이용해서 객체의 멤버를 접근하는 경우에 발생하는 예외 … ©숙대 창병모
사용자 정의 예외 클래스 예 public class NegativeInputException extends Exception { private String reason=“Negative grade”; NegativeInputException( ) { System.out.println(reason + “is received”); } ©숙대 창병모
throw exception-object; 예외 발생 예외는 throw문을 이용해서 발생시킨다 throw exception-object; throws와는 다름 ©숙대 창병모
예외 처리 예외 발생 시 처리하지 않는 경우 프로그램은 메시지를 내고 종료한다. 메시지는 call stack trace를 포함한다. main 메쏘드부터 호출과정 ©숙대 창병모
예외 처리: try-catch 문 Exceptions are caught in try-catch blocks 구문 구조 … catch (En x) { … } ©숙대 창병모
예외 처리: finally 절 try { … } catch (E1 x) { … } finally 절은 옵션 … catch (En x) { … } finally { … } finally문은 예외 발생 여부에 관계없이 항상 수행된다 ©숙대 창병모
예외 처리 예제 class GradeDist { Scanner scan = new Scanner (System.in); int newGrade; int[ ] freq = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} void buildDist( ) throws IOException { Scanner scan = new Scanner (System.in); try { while (true) { System.out.println(“Please input a grade”); newGrade = scan.nextInt( ); if (newGrade < 0) throw new NegativeInputException( ); index = newGrade / 10; freq[index]++; } catch(NegativeInputException x) { // 점수 분포 프린트 … ©숙대 창병모
예외 처리 예제 try { freq[index]++; } catch (ArrayIndexOutOfBoundsException x) { if (newGrade == 100) freq[9]++; else System.out.println(“Error:” + newGrade + “is out of range”); ©숙대 창병모
예외 전파(Exception Propagation) 처리되지 않는 예외 전파 호출의 역순으로 처리될 때까지 전파된다. main() 메소드까지 전파된다. main()에서도 처리되지 않으면 프로그램 종료 ©숙대 창병모
예외 전파: 예제 public class Propagation_Demo { static public void main (String[] args) { Exception_Scope demo = new Exception_Scope(); System.out.println("program beginning"); demo.level1(); System.out.println("program ending"); } // method main } // class Propagation_Demo ©숙대 창병모
예외 전파: 예제 class Exception_Scope { public void level3 (int adjustment) { int current = 1; System.out.println("level3 beginning"); current = current / adjustment; System.out.println("level3 ending"); } // method level3 public void level2() { System.out.println("level2 beginning"); level3 (0); System.out.println("level2 ending"); } // method level2 public void level1() { System.out.println("level1 beginning"); try { level2(); } catch (ArithmeticException problem) { System.out.println (problem.getMessage()); problem.printStackTrace(); } System.out.println("level1 ending"); } // method level1 } // class Exception_Scope ©숙대 창병모
예외 검사 검사 예외(checked exception) 비검사 예외(unchecked exception) 사용자 정의 예외로 컴파일러가 처리 가능 여부를 미리 검사하는 예외 처리되지 않는 예외는 메소드 헤더 부분에 throws를 이용하여 선언되어야 한다. 비검사 예외(unchecked exception) RuntimeException로부터 상속 받는 표준 런타임 예외 처리 여부를 컴파일러가 검사하지 않는 예외 ©숙대 창병모
예외 명세 처리되지 않은 검사 예외를 메소드 이름 뒤에 명세 throws 절 이용 메소드_이름(…) throws A, B, C { . . . } ©숙대 창병모
컴파일러의 예외 검사 컴파일-시간 예외 검사 발생 가능한 예외가 처리될 수 있는지 아니면 메소드 선언 시 명세 되었는지 컴파일-시간 검사 OOOException must be caught or declared to be thrown. 호출된 메소드에서 처리되지 않는 예외 메소드 선언에 명세된 처리되지 않는 예외 정보를 이용 ©숙대 창병모
예외 검사: 예제 // 발생된 예외의 전파과정을 보인다. public class Propagate2 { void input() throws NegativeInputException { int age; Scanner scan = new Scanner(System.in); System.out.println("input 메소드 시작"); age = scan.nextInt( ); if (age < 0) throw new NegativeInputException( ); System.out.println("input 메소드 끝"); } void via() throws NegativeInputException { System.out.println("via 메소드 시작"); input(); System.out.println("via 메소드 끝"); ©숙대 창병모
예외 검사: 예제 public static void main(String[] args) { Propagate2 p = new Propagate2(); System.out.println("main 메소드 시작"); try { p.via(); } catch (NegativeInputException m) { System.out.println(m); } System.out.println("main 메소드 끝"); ©숙대 창병모
요약 Structured Programming Exceptions Go to considered harmful “structured” jumps dynamic scoping of exception handler ©숙대 창병모