윤 홍 란 hryun@sookmyung.ac.kr 5장 조건문과 반복문 윤 홍 란 hryun@sookmyung.ac.kr
조건과 반복 5장에서는 : 부울식(boolean expressions) 조건문(conditional statements) 데이터비교(comparing data) 반복문(repetition statements) 반복자(iterators) 조건과 반복을 이용한 drawing GUI component와 이벤트처리
Outline if 문과 조건 다른 조건문 데이터 비교 While문 반복자(Iterators) 다른 반복문 결정과 그래픽 GUI 컴포넌트
제어의 흐름 특별한 경우가 아니면, 문장의 실행 순서는 순차적으로 수행된다. 몇몇 프로그래밍 문장은 이 순서를 바꾸도록 해준다. : 특정한 문장을 수행할지 안 할지 결정할 수 있게 하고 문장을 반복적으로 실행시킬수도 있다. 이러한 결정은 부울식이나 조건에 의해 결과가 참이나 거짓으로 나오게 함으로써 이루어진다. 문장의 실행 순서를 제어의 흐름(flow of control)이라고 한다.
조건문(Conditional Statements) 조건문은 어떤 문장을 다음에 수행시킬지를 결정할 수 있게 한다. 따라서, 때때로 선택문(selection statements)이라고도 한다. 조건문은 기본적인 결정을 할 수 있도록 해준다. Java에서 조건문은 if 문 if-else 문 switch 문
if 문 if 문의 구조 조건은 반드시 부울식이여야하고 따라서 결과가 참이나 거짓으로 나온다. if 는 Java의 예약어(reserved word) if ( 조건식 ) 문장; 조건식의 결과가 참이면, 문장이 실행되고, 거짓이면 문장은 실행되지 않는다.
if문의 로직 condition evaluated false statement true
부울식(Boolean Expressions) 조건은 자바의 동등연산자(equality operators)나 관계연산자를 사용한다. == equal to != not equal to < less than > greater than <= less than or equal to >= greater than or equal to 주의 : 동등연산자(==) 와 대입/배정 연산자 (=)
if 문 if문 예제: if (sum > MAX) delta = sum - MAX; See Age.java (page 214) if (sum > MAX) delta = sum - MAX; System.out.println ("The sum is " + sum); import java.util.Scanner; public class Age { public static void main (String[] args) final int MINOR = 21; Scanner scan = new Scanner (System.in); System.out.print ("Enter your age: "); int age = scan.nextInt(); System.out.println ("You entered: " + age); if (age < MINOR) System.out.println ("Youth is a wonderful thing. Enjoy."); System.out.println ("Age is a state of mind."); }
if 문 아래 문장의 의미는? if (top >= MAXIMUM) top = 0; if (total != stock + warehouse) inventoryError = true; 산술연산자는 동등연산자나 관계연산자에 비해 우선순위가 높다.
논리연산자(Logical Operators) 결과가 참이나 거짓으로 나오게 되는 논리식은 논리연산자를 사용할 수 있다. ! Logical NOT && Logical AND || Logical OR 논리식의 결과는 결과가 참이나 거짓인 boolean값을 갖는다. Logical NOT은 단항연산자이다.(즉, 하나의 피연산자만이 필요하다.) Logical AND와 Logical OR는 이항연산자이다.(즉, 연산을 위해 두개의 피연산자가 필요하다.)
논리 NOT 부울값이 참이면 거짓이 거짓이면 참이 된다. 논리 연산은 아래 진리표에 의해 기술된다. a !a true false
논리 AND 와 논리 OR 논리 AND 식은 : a && b 논리 OR 식은 : a || b true false
논리 연산자 논리 연산자를 사용하는 식은 복잡한 조건 형태를 가질 수 있다. 모든 논리 연산자는 관계연산자보다 우선순위가 낮다. 논리NOT은 논리AND와 논리OR보다 우선순위가 높다. if (total < MAX+5 && !found) System.out.println ("Processing…");
연산자 우선 순위 우선순위 연산자 연관성 1 ++ -- + - ~ ! (캐스트) 오른쪽 -> 왼쪽 2 * / % 왼쪽 -> 오른쪽 3 + - 4 << >> >>> 5 < > <= >= instanceof 6 == != 7 & 8 ^ 9 | 10 && 11 || 12 ?: 13 = *= /= %= += -= <<= >>= >>>= &= ^= |=
Outline if 문과 조건 다른 조건문 데이터 비교 While문 반복자(Iterators) 다른 반복문 결정과 그래픽 GUI 컴포넌트
if-else 문 else구문은 if문에 추가되어 if-else문을 구성한다. 둘중에서 한쪽만 수행되도록 한다. See Wages.java (page 216) 피고용인이 한주에 40시간 이상 일하면, 급여는 초과 시간 근무를 고려 한다. if-else문을 사용하여 사용자가 입력한 근무 시간이 40보다 큰지 를 결정한다. 그럴 경우에, 초과시간에 대한 급여는 정상 급여 비율의 1.5배를 적용하여 계산된다. 만약, 초과근무시간이 없다면, 총 급여는 단지 일한 근무시간에 기초하여 계산된다. if ( 조건 ) 조건이 참일때 수행될 문장; else 조건이 거짓일때 수행될 문장;
Wages.java import java.text.NumberFormat; import java.util.Scanner; public class Wages { public static void main (String[] args) final double RATE = 8.25; // regular pay rate final int STANDARD = 40; // standard hours in a work week Scanner scan = new Scanner (System.in); double pay = 0.0; System.out.print ("Enter the number of hours worked: "); int hours = scan.nextInt(); System.out.println (); // Pay overtime at "time and a half" if (hours > STANDARD) pay = STANDARD * RATE + (hours-STANDARD) * (RATE * 1.5); else pay = hours * RATE; NumberFormat fmt = NumberFormat.getCurrencyInstance(); System.out.println ("Gross earnings: " + fmt.format(pay)); }
if-else 문의 로직 condition evaluated false statement2 statement1 true
Coin Class See CoinFlip.java (page 218) See Coin.java (page 219)
Coin.java public class Coin { private final int HEADS = 0; private final int TAILS = 1; private int face; //---------------------------------- // Sets up the coin by flipping it initially. public Coin () flip(); } // Flips the coin by randomly choosing a face //value. public void flip () face = (int) (Math.random() * 2); //---------------------------------- // Returns true if the current face of the coin is //heads. public boolean isHeads () { return (face == HEADS); } //---------------------------------- // Returns the current face of the coin as a //string. //--------------------------------- public String toString() String faceName; if (face == HEADS) faceName = "Heads"; else faceName = "Tails"; return faceName;
CoinFlip.java public class CoinFlip { //----------------------------------------------------------------- // Creates a Coin object, flips it, and prints the results. public static void main (String[] args) Coin myCoin = new Coin(); myCoin.flip(); System.out.println (myCoin); if (myCoin.isHeads()) System.out.println ("You win."); else System.out.println ("Better luck next time."); }
블럭문 사용(Block Statements) 부울식의 평가 결과로 하나의 문장 이상의 것을 수행하고자 할 때 블럭문을 사용한다. – 물론 단일문의 경우에 블럭문을 사용해도 상관없다. if (total > MAX) { System.out.println ("Error!!"); errorCount++; }
블럭문(Block Statements) if-else문의 경우에도 사용 if (total > MAX) { System.out.println ("Error!!"); errorCount++; } else System.out.println ("Total: " + total); current = total*2;
See Guessing.java (page 216) import java.util.*; public class Guessing { public static void main (String[] args) final int MAX = 10; int answer, guess; Scanner scan = new Scanner (System.in); Random generator = new Random(); answer = generator.nextInt(MAX) + 1; System.out.print ("I'm thinking of a number between 1 and " + MAX + ". Guess what it is: "); guess = scan.nextInt(); if (guess == answer) System.out.println ("You got it! Good guessing!"); else System.out.println ("That is not correct, sorry."); System.out.println ("The number was " + answer); } See Guessing.java (page 216)
조건 연산자 자바는 부울식을 사용하여 두 연산식중에 하나만을 실행시킬 수 있도록 하는 조건 연산자를 가진다. 문법은 : 조건 ? 연산식1 : 연산식2 만약 조건이 참이면 연산식1을 조건이 거짓이면 연산식2를 수행한다. 조건연산자가 들어간 식의 최종 값은 선택된 연산식의 결과가 된다. 조건 연산자는 if-else문과 비슷하나 식의 결과가 결정된 연산식의 결과라는 것이 차이가 있다. 예를 들어: larger = ((num1 > num2) ? num1 : num2); num1이 num2보다 크면, num1이 larger에 배정되고 그렇지 않으면 num2가 larger에 배정된다. 조건 연산자는 삼항 연산자이다. System.out.println ("Your change is " + count + ((count == 1) ? "Dime" : "Dimes"));
중첩된 if 문 if문에서 실행되는 문장이 또다른 if문이 될 수 있다. 이럴 경우 중첩 if문이라고 한다. import java.util.Scanner; public class MinOfThree { public static void main (String[] args) int num1, num2, num3, min = 0; Scanner scan = new Scanner (System.in); System.out.println ("Enter three integers: "); num1 = scan.nextInt(); num2 = scan.nextInt(); num3 = scan.nextInt(); if (num1 < num2) if (num1 < num3) min = num1; else min = num3; if (num2 < num3) min = num2; System.out.println ("Minimum value: " + min); } if문에서 실행되는 문장이 또다른 if문이 될 수 있다. 이럴 경우 중첩 if문이라고 한다. See MinOfThree.java (page 224)
switch문 switch 문은 연산식의 결과에 따라 가능한 case중의 하나를 따라가서 실행하도록 한다. 여러가지 조건에 따라 문장을 서로 다르게 처리하기 위함. If 문의 구조화된 형태 switch (option) { case 'A': aCount++; break; case 'B': bCount++; case 'C': cCount++; }
switch 문 switch ( expression ) { case value1 : statement-list1 The general syntax of a switch statement is: switch ( expression ) { case value1 : statement-list1 case value2 : statement-list2 case value3 : statement-list3 case … …… default : } 테스트할 식 switch 라는 예약어와 case 라는 예약어 평가식이 value2와 일치하면, 제어 흐름이 여기로 바뀐다. 평가식의 값이 일치하는 경우가 없을때, 제어 흐름이 여기로 바뀐다.
if문으로 switch 문의 역할을 하는 경우 Condition Evaluted Evalution Value 1 false Evalution Value 2 true false Statement_list1 Evalution Value 3 true false true Statement_list2 Statement_list3 Statement_default
switch 문 Value1 Value2 default Statement_list1 Statement_list2 Condition Evaluted Value1 Value2 default Statement_list1 Statement_list2 . . . . . . . Statement_default
switch 문 break statement default case break 문이 사용되었을때 switch 문의 각 case 문을 빠져 나옴. switch 문의 끝으로 제어를 옮김. break 문은 한번에 하나씩 자신을 둘러싸고 있는 문장에서 빠져 나옴. break 문이 사용되지 않았을때 다음 case 문으로 제어가 진행됨. default case 선택적으로 사용됨. 사용 되면 어떤 경우와도 일치되지 않으면, 디폴트 경우가 실행됨. 생략 되면 switch 문에 속한 어떤 문장도 실행되지 않고, switch문 다음에 오는 문장이 실행됨. default라는 예약어를 사용 보통 switch 문의 끝에 사용됨. switch 문의 어느 위치에 사용되어도 상관 없음.
switch 문 Switch 문의 평가식은 정수형 데이터 타입이나 char타입 이어야 함. integer or character 값을 갖음. boolean or floating point 값은 안됨. 일치되는 경우의 값(case value)은 상수 이어야 함. 변수 또는 수식은 안됨. switch 문의 묵시적 부울 조건은 동등성에 근거함. 평가식을 각 경우의 값과 비교하여, 어느 경우와 동등한지를 결정 Expression은 특정 값과 일치하기 때문 관계 연산을 할 수는 없음. See GradeReport.java (page 231) switch 문은 일련의 if-else 구문으로 표현될 수 있음. Switch 문이 편리, 판독성 좋음.
GradeReport.java switch (category) { case 10: System.out.println ("a perfect score. Well done."); break; case 9: System.out.println ("well above average. Excellent."); case 8: System.out.println ("above average. Nice job."); case 7: System.out.println ("average."); case 6: System.out.println ("below average. “ + You should see the"); System.out.println ("instructor to clarify the material " + "presented in class."); default: System.out.println ("not passing."); } import java.util.Scanner; public class GradeReport { public static void main (String[] args) int grade, category; Scanner scan = new Scanner (System.in); System.out.print ("Enter a numeric” + grade (0 to 100): "); grade = scan.nextInt(); category = grade / 10; System.out.print ("That grade is ");
Outline if 문과 조건 다른 조건문 데이터 비교 While문 반복자(Iterators) 다른 반복문 결정과 그래픽 GUI 컴포넌트
데이터 비교 부울식을 이용하여 데이터를 비교할 때, 데이터 타입에 따른 차이를 이해해야 한다. 아래의 다양한 상황에 따른 데이터 비교를 살펴보면: 동등 비교하기 위한 floating point values Characters비교 strings (alphabetical order) 비교 객체 비교와 객체 참조 비교(Comparing object vs. comparing object references)
부동소숫점(Float Values) 비교 두개의 floating point values(float or double)를 비교할 때는 동등연산자 (==)를 사용하지 않는 것이 좋다. 두개의 floating point values는 기계 표현에서 모든 이진수가 동일한 경우에 한해서 동등하다. 비교되고 있는 값들이 계산된 결과이면, 그들이 특정 상황에서 충분히 근사한 값을 가질지라도 정확히 동등하지 않을 수 있다. 부동소숫점값의 동등함을 검사하는 방법은 두 값 간의 차이의 절대값을 계산하고 그 결과를 어떤 임계값과 비교하는 것이다. 가령, 0.00001의 임계값을 선택할 수 있다. 두 부동 소수점 값들이 그 차가 임계값보다 작을 정도로 근사할 경우에 그것들이 동등하다고 판단한다. if (Math.abs(f1 - f2) < TOLERANCE) System.out.println ("Essentially equal");
문자 비교 자바의 문자는 Unicode character set에 기반한다. 이 순서를 이용하여 관계연산자를 사용할 수 있다. 결과는 True 임. '+' 문자가 'J' 문자 보다 앞에 있으므로 대문자 the uppercase alphabet (A-Z), 소문자 the lowercase alphabet (a-z) 순으로 나옴. 문자 정렬을 가능하게 함. Appendix C provides an overview of Unicode if ('+' < 'J') System.out.println ("+ is less than J"); Characters Unicode Values 0 – 9 48 through 57 A – Z 65 through 90 a – z 97 through 122
스트링 비교 Java 스트링은 객체이다. equals 메소드는 두개의 스트링이 정확하게 같은 문자열 구조를 가지는 경우 참이나 거짓을 반환한다. equals 메소드는 부울값(참/거짓)을 반환한다. if (name1.equals(name2)) System.out.println ("Same name");
스트링 비교 스트링을 비교할때는 관계연산자를 사용할 수 없다. 스트링 클래스에는 compareTo라고 불리는 메소드를 가지고 있다. 이 메소드는 두개의 스트링을 비교한다. name1.compareTo(name2) 라고 사용하면, name1 과 name2 가 같으면 0을 반환 name1이 name2보다 작으면 음수값 반환 name1이 name2보다 크면 양수값 반환 if (name1.compareTo(name2) < 0) System.out.println (name1 + "comes first"); else if (name1.compareTo(name2) == 0) System.out.println ("Same name"); System.out.println (name2 + "comes first");
스트링 비교 문자와 스트링 비교는 유니코드 문자집합에 기초하며 이것을 사전식순서(lexicographic ordering)한다. 사전식순서(Lexicographic ordering) 정확하게 사전식 순서는 아니다. 대소문자가 혼합되어 있는 경우 유니코드 문자집합에서 모든 대문자가 모든 소문자보다 순서상 앞에 있다. 예를 들어, "Great“는 스트링 "fantastic"보다 앞에 위치한다. 또한 한 스트링이 다른 스트링의 접두어이면, 이 스트링이 더 긴 스트링보다 순서 상 앞에 온다 따라서 "book“이 스트링 "bookcase"보다 순서상 먼저 온다고 결정한다.