프로그래밍/JAVA

자바 조건문과 반복문

나도 오늘부터 개발자?! 2021. 12. 20. 21:30

자바 수업을 들은지 오늘로 4일째.... 자바의정석 Chap4에서 if-else if문에서 책과는 다르게 내가 만들어보고 싶어서 예시를 만들던 도중 에러가 났습니다!! 


Syntax 어쩌구 token else 에러 ?! 이게 무슨 말이지... 
10여분간 스펠링이 틀린곳은 없는지 책이랑은 다른게 쓴곳은 없는지 고민을 하다가 못 찾고 있었는데 문득 개발자는 프로 구글러라는 이야기가 떠올라 바로 구글에 자바 token else 라고 검색을 한 결과


자바에서 토큰 else 구문 오류를 해결하는 방법을 찾았습니다!


저자분도 저와 같은 오류가 나서 해결방법을 찾고 있었던거 같아요 그리고 답변을 달아주신 분께서 답을 가르쳐주셨습니다


그렇답니다 ~ 그리고 오늘은 자바 챕터 4의 연습문제와 학원에서 준 퀴즈가 있어서 풀어보고 있는데 굉장히 어렵네요 후.. 오늘 안에 다 끝낼수 있을지 모르겠지만 내일 다시 자료랑 함께 글 올리겠습니다! 글 읽어주셔서 감사합니다!

 

 

(책에 나온 조건문과 반복문 작성하기)

 제어문(flow control statement): 조건문과 반복문이 있으며, 프로그램의 흐름(flow)을 바꾸는 역할을 한다. 조건문은 조건에 따라 다른 문장이 수행되고, 반복문은 특정 문장들을 반복해서 수행한다.

● 조건문: if문과 switch문이 있으며 처리할 경우의 수가 많을 때는 switch문이 효율적이지만 제약이 많다.

1. if문

- 만일(if) 조건이 참(true)이면 괄호{}안의 문장들을 수행한다.

- 블럭(block): 여러 문장을 하나의 단위로 묶는 괄호{}. 끝에 ;을 붙이지 않는다. 블럭 내의 문장들은 탭(tab)으로 들여쓰기(indentation)을 해서 블럭 안에 속한 문장이라는 것을 표시해 준다. 만일 블럭 내의 문장이 하나뿐일 때는 괄호{}를 생략할 수 있다.

▶ if-else문

- 조건식의 결과가 거짓ㅇ리 때 else블럭의 문장을 수행한다

- if문을 두 개 사용할 경우 두 개의 조건식을 계산해야 하지만, if-else문을 사용할 경우 하나의 조건식만 계산하면 되므로 더 효율적이고 간단하다.

- 블럭 내의 문장이 하나일 경우 괄호{}를 생략할 수 있다.

▶ if-else if문

- 여러 개의 조건식을 쓸 때 사용한다.

- 첫 번째 조건식부터 순서대로 평가해서 결과가 참인 조건식을 만나면, 해당 블럭{}만 수행하고 "if-else if"문 전체를 벗어난다.

- 만일 결과가 참인 조건식이 하나도 없으면, 마지막에 있는 else블럭의 문장들이 수행된다. 그리고 else블럭은 생략이 가능하다.

▶ 중첩 if문

- if문의 블럭 내에 또 다른 if문을 포함시키는 것.

if (조건식1) {
    // 조건식1의 연산결과가 true일 때 수행될 문장들을 적는다.
    if (조건식2) {
        // 조건식1과 조건식2가 모두 true일 때 수행될 문장들
    } else {
        // 조건식1이 true이고, 조건식2가 false일 때 수행되는 문장들
    }
} else {
    // 조건식1이 false일 때 수행되는 문장들
}

2. switch 문

- 조건식의 결과가 참과 거짓, 두 가지 밖에 없기 때문에 경우의 수가 많아질 수록 else-if를 계속 추가해야 해서 조건식이 많아지므로 복잡해지는 if문과는 달리, swtich문은 단 하나의 조건식으로 많은 경우의 수를 처리할 수 있고, 표현도 간결하므로 알아보기 쉽다. 그래서 처리할 경우의 수가 많은 경우에는 if문보다 switch문으로 작성하는 것이 좋다.

- 순서: 1) 조건식을 계산한다. 2) 조건식의 결과와 일치하는 case문으로 이동한다. 3) 이후의 문장들을 수행한다. 4) break문이나 switch문의 끝을 만나면 switch의 전체를 빠져나간다.

- 맨 마지막의 default는 조건식의 결과가 일치하는 case이 하나도 없을 경우에 이동한다. 보통 마지막에 위치하기 때문에 break문을 쓰지 않아도 된다.

- break문은 각 case문의 영역을 구분하는 역할을 하며, 만일 생략하면 case문 사이의 구분이 없어지므로 다른 break문을 만나거나 swtich문 블럭{}의 끝을 만날 떄까지 나오는 모든 문장들을 수행한다.

// 다음과 같이 고의적으로 break문을 생략하는 경우도 있다.
switch (level) {
    case 3: 
        grantDelete();        // 삭제 권한을 준다.
    case 2:
        grantWrite();        // 쓰기 권한을 준다.
    case 1:
        grantRead();        // 읽기 권한을 준다.
}

// 로그인한 사용자의 등급을 체크하여 제일 높은 등급인 3을 가진 사용자는 삭제, 쓰기, 읽기 권한

// 모두를 갖게 되고, 제일 낮은 등급인 1을 가진 사용자는 읽기 권한만을 갖게 된다.

- 조건: 1) swtich문의 조건식의 결과값은 반드시 정수 또는 문자열이어야 한다. 2) case문의 값 역시 정수, 정수 상수 (대문자 변수), 문자열, 또는 문자 리터럴(사실은 정수인 유니코드로 저장되기 때문)이어야 하고, 중복되지 않아야 한다.

- case문은 한 줄에 하나씩 쓰던, 한 줄에 붙여서 쓰던 관계 없다.

 
switch (result) {
    case 1:
    case 2:
    case 3:
        System.out.println("A+ 입니다");
        break;
}
switch (result) {
    case 1: case 2: case 3:
        System.out.println("A+ 입니다");
        break;
}

- switch문은 조건식을 1번만 계산하면 되므로 더 빠르다. 반드시 속도를 향상시켜야 한다면 복잡하더라도 switch를 선택할 수 있지만, 그렇지 않다면 if문이 더 적합한 경우도 있다. switch문에서는 조건식을 잘 만들어서 case의 갯수를 줄이는 것이 중요하다.

- swtich문의 중첩: 중첩이 가능하다. 한 가지 중요한 점은 중첩 switch문의 블럭 뒤에 반드시 break문을 빼먹지 않아야 한다는 점이다.

 
 

 반복문: 어떤 작업이 반복적으로 수행될 때 사용되며, for문과 while문, 그리고 do-while문이 있다. 반복문은 주어진 조건을 만족하는 동안 주어진 문장들을 반복적으로 수행하므로 조건식을 포함한다. for문과 while문에 속한 문장은 조건에 따라 한 번도 수행되지 않을 수 있지만, do-while문에 속한 문장은 무조건 최소한 한 번은 수행될 것이 보장된다. for문과 while문 중 어떤 반복문을 선택해도 괜찮지만, for문은 주로 반복 횟수를 알고 있을 때 사용한다.

1. for문

- 조건이 참일 동안 블러{} 내의 문장들을 반복하다 거짓이 되면 반복문을 벗어난다.

- 순서: 1) 초기화 2) 조건식-조건식이 참일 동안 3) 수행될 문장 4) 증감식

- 초기화: 둘 이상의 변수가 필요할 때는 콤마(',')를 구분자로 변수를 초기화 하면 되며, 두 변수의 타입은 같아야 한다.

- 증감식: 증감 연산자 ++, --, 복합 대입 연산자 +=, *= 등 사용가능하다. 쉼표(',')를 이용해서 두 문장 이상을 하나로 연결해서 쓸 수 있다.

for (int i = 1, j = 10; i <= 10; i++, j--) {
    ....
}

- 초기화, 조건식, 증감식은 생략 가능하며, 세 가지 모두를 생략할 경우 조건식은 참이 되어 무한 반복문이 된다. 대신 블럭{} 안에 if문을 넣어서 특정 조건을 만족하면 for문을 빠져 나오게 해야 한다.

 
for (;;) {
     ....
}
 
// 나머지 연산자(%)를 사용하면 특정 범위의 값들이 순환하면서 반복되는 결과를 얻을 수 있다.
// 나누기 연산자(/)는 같은 값이 연속적으로 반복되게 할 수 있다.

2. 중첩 for문: for문의 블럭 안에 다른 for문을 포함시키는 것.

- 만약 중첩 for문이 3개 이고, 각 반복문이 3번씩 반복하면, 모두 (3*3*3=27) 27번이 반복된다.

3. 향상된 for문 (enhanced for statement)

for (타입 변수명 : 배열 또는 컬렉션) {
    // 반복할 문장
}

- 타입은 배열 또는 컬렉션의 요소의 타입이어야 한다.

- 배열 또는 컬렉션에 저장된 값이 매 반복마다 하나씩 순서대로 읽혀서 변수에 저장된다. 그리고 반복문의 괄호{} 내에서는 이 변수를 사용해서 코드를 작성한다.

- 향상된 for문은 배열이나 컬렉션에 저장된 요소들을 읽어오는 용도로만 사용할 수 있다는 제약이 있다.

 
for(int i = 0; i < arr.length; i++) {
    System.out.println(arr[i]);
}

for(int num : arr) {
    System.out.println(num);
}

 

● while문: 먼저 조건식을 평가해서 조건식이 거짓이면 문장 전체를 벗어나고, 참이면 블럭{} 내의 문장을 수행하고 다시 조건식으로 돌아간다. 조건식이 거짓이 될 때까지 이 과정이 계속 반복된다. for문과 while문은 항상 서로 변환이 가능하지만, 초기화나 증감식이 필요하지 않는 경우라면 while문이 더 적합하다.

- 조건식에서 호위형의 증감식이 쓰일 경우: 조건식이 평가된 후에 i의 값이 증감한다.

- while문의 조건식 안에 true값이 저장된 변수를 넣으면 변수가 고정된 값을 유지하므로 무한반복된다. 이런 경우 특정조건을 만족할 때 반복을 멈추게 하는 if문(변수 값을 false로 바꿔주는)이 반복문 안에 꼭 필요하다.


- while 문 안의 for문을 아무런 실행 문구 없는 문장으로 넣어(이때 {}를 쓰거나 괄호 생략하고 ;만 끝에 써 주어도 됨) 조건식과 증감식을 x번 반복하면서 while문의 실행 시간을 지연시킬 수 있다.

class FlowEx24 {
	public static void main(String[] args) { 
		int i=11;

		System.out.println("자, 이제 카운트다운을 시작합니다.");

		while(i--!=0) {
			System.out.println(i);

			for(int j=0;j<2_000_000_000;j++) {
					;
			}
		}

		System.out.println("GAME OVER");
	}
}

- 어떤 숫자의 각 자리의 합을 구하는 방식: 어떤 수를 10으로 나머지 연산하면 (% 10) 수의 마지막 자리를 얻을 수 있다. 어떤 수를 10으로 나누면 (/ 10) 마지막 한자리가 제거된다. x /= 10에 의해 한자리씩 줄어들다가 0이 되면, while문을 빠져나가는 조건식 (x!=0)을 사용해서 반복을 멈출 수 있다. (끝에 자리가 0인 것을 제외시키려면 x % 10 != 0이라는 조건을 추가하면 된다)

import java.util.*;

class FlowEx25 {
	public static void main(String[] args) { 
		int num = 0; 
		int sum = 0;

		System.out.print("숫자를 입력하세요.(예:12345)>");
		Scanner scanner = new Scanner(System.in);
		String tmp = scanner.nextLine(); // 화면을 통해 입력받은 내용을 tmp에 저장
		num = Integer.parseInt(tmp);      // 입력받은 문자열(tmp)을 숫자로 변환

		while(num!=0) {    
			// num을 10으로 나눈 나머지(끝 자리 수)를 sum에 더함
			sum += num%10; 	// sum = sum + num%10;
			System.out.printf("sum=%3d num=%d%n", sum, num);

			num /= 10;  // num = num / 10;  num을 10으로 나눈 값을 다시 num에 저장(끝자리 제거)
		}
		
		System.out.println("각 자리수의 합:"+ sum);
	}
}

- 1부터 몇까지 더하면 누적합계가 x을 넘지 않은 제일 큰 수가 되는지: sum += ++i <= 100으로 조건식을 사용해서 구할 수 있다.

 

class FlowEx26 {
	public static void main(String[] args) { 
		int sum = 0;
		int i   = 0;

		while((sum += ++i) <= 100) { // i를 1씩 증가시켜서 sum에 계속 더해나간다.
			System.out.printf("%d - %d%n", i, sum);
		}
	} // main의 끝
}

● do-while문: 블럭{}을 먼저 실행한 후에 조건식();을 평가한다. while문은 조건식의 결과에 따라 블럭{}이 한 번도 수행되지 않을 수 있지만, do-while문은 최소한 한 번은 수행될 것을 보장한다. 끝에 ;을 붙여야 한다.

● break문: 자신이 포함된 가장 가까운 반복문을 벗어난다. 주로 if문과 함께 사용되어 특정 조건을 만족하면 반복문을 벗어나도록 한다.

● continue문: 반복문 내에서만 사용될 수 있으며, 반복이 진행되는 도중에 continue문을 만나면 반복문의 끝으로 이동하여 다음 반복문으로 넘어간다. for문의 경우 증감식으로 이동하며, while문과 do-while문의 경우 조건식으로 이동한다. 반복문 전체를 벗어나지 않고 다음 반복을 계속 수행한다. 주로 if문과 함께 사용되어 특정 조건을 만족하는 경우에 continue문 이후에 문장들을 수행하지 않고 다음 반복으로 넘어가서 계속 진행하도록 한다. 전체 반복 중에 특정 조건을 만족하는 경우를 제외하고자 할 때 유용하다.

● 이름 붙은 반복문: 여러 개의 반복문이 중첩된 경우에는 중첩 반복문 앞에 이름을 붙이고 break문과 continue문에 이름을 지정해 줌으로써 하나 이상의 반복문을 벗어나거나 반복을 건너뛸 수 있다.

class FlowEx33 {
	public static void main(String[] args)
	{
        // for문에 Loop1이라는 이름을 붙였다.
		Loop1 : for(int i=2;i <=9;i++) {	
				for(int j=1;j <=9;j++) {
					if(j==5)
						break Loop1;
//						break;
//						continue Loop1;
//						continue;
					System.out.println(i+"*"+ j +"="+ i*j);
				} // end of for i
				System.out.println();
		} // end of Loop1

	}
}
import java.util.*;

class FlowEx34 {
	public static void main(String[] args) { 
		int menu = 0;
		int num  = 0;

		Scanner scanner = new Scanner(System.in);

		outer:           // while문 앞에 outer이라는 이름을 붙였다.
		while(true) {
			System.out.println("(1) square");
			System.out.println("(2) square root");
			System.out.println("(3) log");
			System.out.print("원하는 메뉴(1~3)를 선택하세요.(종료:0)>");

			String tmp = scanner.nextLine(); // 화면에서 입력받은 내용을 tmp에 저장
			menu = Integer.parseInt(tmp);    // 입력받은 문자열(tmp)을 숫자로 변환

			if(menu==0) {  
				System.out.println("프로그램을 종료합니다.");
				break;
			} else if (!(1<= menu && menu <= 3)) {
				System.out.println("메뉴를 잘못 선택하셨습니다.(종료는 0)");
				continue;		
			}

			for(;;) {
		    System.out.print("계산할 값을 입력하세요.(계산 종료:0, 전체 종료:99)>");
				tmp = scanner.nextLine();   // 화면에서 입력받은 내용을 tmp에 저장
				num = Integer.parseInt(tmp); // 입력받은 문자열(tmp)을 숫자로 변환

				if(num==0)  
					break;        // 계산 종료. for문을 벗어난다.
				if(num==99) 
					break outer;  // 전체 종료. for문과 while문을 모두 벗어난다.

				switch(menu) {
					case 1: 
						System.out.println("result="+ num*num);		
						break;
					case 2: 
						System.out.println("result="+ Math.sqrt(num)); 
						break;
					case 3: 
						System.out.println("result="+ Math.log(num));  
						break;
				} 
			} // for(;;)
		} // while의 끝
	} // main의 끝
}

'프로그래밍 > JAVA' 카테고리의 다른 글

[유튜브 : 뉴렉처님 강의] JDBC 1~ 12강 CRUD  (0) 2022.10.19
자바 객체지향(2)  (0) 2021.12.29
자바 객체지향 (1)  (0) 2021.12.28
자바의정석 Chap 5 배열 두둥!  (0) 2021.12.22
Java 변수(variable)  (0) 2021.12.17