본문 바로가기
공부기록/자바

Chapter 04. 조건문과 반복문

by 루팽 2022. 11. 22.

코드 실행 흐름 제어

자바 프로그램은 main() 메소드의 시작 중괄호({)에서 끝 중괄호(})까지 위에서부터 아래로 실행하는 흐름을 가지고 있음

이러한 실행 흐름을 개발자가 원하는 방향으로 바꿀 수 있도록 해주는 것이 흐름 제어문

제어문은 조건식과 중괄호 {} 블록으로 구성되는데, 조건식의 연산 결과에 따라 블록 내부의 실행 여부가 결정됨

조건문  반복문
if 문, switch 문 for 문, while 문, do-while 문

 

조건문의 경우 정상 흐름으로 돌아오지만 반복문일 경우는 제어문 처음으로 다시 되돌아가 반복 실행되는데 이것을 루핑(looping)이라고 함

제어문 블록 내부에 또 다른 제어문을 사용할 수도 있음

 

if 문

if 문은 조건식의 결과에 따라 블록 실행 여부가 결정됨

조건식이 true면 블록을 실행하고 false면 블록을 실행하지 않는다

if (조건식) {
	실행문;
	실행문;
	...
}

if (조건식)
	실행문;
//실행문이 하나밖에 없다면 중괄호 생략 가능하지만 생략하지 않는 것을 추천

 

package ch04.sec02;

public class IfExample {
	public static void main(String[] args) {
		int score = 93;
		
		if(score >= 90) {
			System.out.println("점수가 90 이상입니다.");
			System.out.println("등급은 A 입니다.");
		}
		
		if(score < 90)
			System.out.println("점수가 90 미만입니다."); //{} 생략
		System.out.println("등급은 B 입니다."); //if 문과 상관없이 출력되는 실행문

		//점수가 90 이상입니다. 등급은 A 입니다. 등급은 B 입니다.
	}
}

 

package ch04.sec02;

public class IfElseExample {
	public static void main(String[] args) {
		int score = 85;
		
		if(score >= 90) {
			System.out.println("점수가 90 이상입니다.");
			System.out.println("등급은 A 입니다.");
		} else {
			System.out.println("점수가 90 미만입니다.");
			System.out.println("등급은 B 입니다.");
			
			//점수가 90 미만입니다. 등급은 B 입니다.
		}
	}
}

 

package ch04.sec02;

public class IfElseIfElseExample {
	public static void main(String[] args) {
		int score = 75;
		
		if(score >= 90) {
			System.out.println("점수가 100~90점 입니다.");
			System.out.println("등급은 A 입니다.");
		} else if(score >= 80) {
			System.out.println("점수가 89~80점 입니다.");
			System.out.println("등급은 B 입니다.");
		} else if(score >= 70) {
			System.out.println("점수가 79~70점 입니다.");
			System.out.println("등급은 C 입니다.");
		} else {
			System.out.println("점수가 70점 미만입니다.");
			System.out.println("등급은 D 입니다.");
			
			//점수가 79~70점 입니다. 등급은 C 입니다.
		}
	}
}

 

주사위 굴리기 코드 작성

임의의 정수를 뽑는 Math.random() 메소드 활용

0.0 <= Math.random() < 1.0

(0.0 * 6) <= (Math.random() * 6) < (1.0 * 6) //0.0 <= 6.0 사이의 double 타입 난수

(int) 0.0 <= (int) (Math.random() * 6) < (int) 6.0 //int로 강제 타입 변환, 0~5 중 하나의 정수 난수

(0+1) <= ((int) (Math.random() * 6) +1) < (6+1) //1을 더해 1~6 중 하나의 정수 난수

int num = (int) (Math.random() * n) + start; //start부터 시작하는 n개의 정수 중 하나의 정수를 얻는 코드
int num = (int) (Math.random() * 45) +1; // 1~45 중 하나를 뽑기 위한 코드

 

package ch04.sec02;

public class IfDiceExample {
	public static void main(String[] args) {
		int num = (int)(Math.random()*6) + 1; //주사위 번호 하나 뽑기
		
		if(num == 1) {
			System.out.println("1번이 나왔습니다.");
		} else if (num == 2) {
			System.out.println("2번이 나왔습니다.");
		} else if (num == 3) {
			System.out.println("3번이 나왔습니다.");
		} else if (num == 4) {
			System.out.println("4번이 나왔습니다.");
		} else if (num == 5) {
			System.out.println("5번이 나왔습니다.");
		} else {
			System.out.println("6번이 나왔습니다.");
		}
	}
}

 

package ch04.sec02;

public class IfNestedExample {
	public static void main(String[] args) {
		int score = (int)(Math.random()*20) + 81; //81~100 중 하나 뽑기
		System.out.println("점수: " + score);
		
		String grade;
		
		if(score >= 90) {
			if(score >= 95) {
				grade = "A+";
			} else {
				grade = "A";
			}
		} else {
			if(score >= 85) {
				grade = "B+";
			} else {
				grade = "B";
			}
		}
		
		System.out.println("학점: " + grade);
	}
}

 

switch 문

if문은 조건식의 결과가 true, false 두 가지밖에 없기에 경우의 수가 많아질수록 복잡해지지만,

switch 문은 변수의 값에 따라서 실행문이 결정되기에 같은 기능의 if 문보다 코드가 간결해짐

switch 문은 괄호 안의 변수값에 따라 해당 case로 가서 실행문을 실행시킴

만약 변수값과 동일한 값을 갖는 case가 없으면 default로 가서 실행문 실행시킴

default가 필요 없다면 생략 가능

package ch04.sec03;

public class SwitchExample {
	public static void main(String[] args) {
		int num = (int)(Math.random()*6) +1; //주사위 번호 하나 뽑기
		
		switch(num) {
		case 1:
			System.out.println("1번이 나왔습니다.");
			break;
		case 2:
			System.out.println("2번이 나왔습니다.");
			break;
		case 3:
			System.out.println("3번이 나왔습니다.");
			break;
		case 4:
			System.out.println("4번이 나왔습니다.");
			break;
		case 5:
			System.out.println("5번이 나왔습니다.");
			break;
		default:
			System.out.println("6번이 나왔습니다.");
		}
	}
}

 

case 끝에 있는 break는 다음 case를 실행하지 않고 switch문을 빠져나가기 위해 필요

민액 break가 없다면 case 값과는 상관없이 다음 case가 연달아 실행됨

package ch04.sec03;

public class SwitchNoBreakCaseExample {
	public static void main(String[] args) {
		int time = (int)(Math.random()*4) + 8; //8~11 사이의 정수 뽑기
		System.out.println("[현재 시간: " +time + "시]");
		
		switch(time) {
		case 8:
			System.out.println("출근합니다.");
		case 9:
			System.out.println("회의를 합니다.");
		case 10:
			System.out.println("업무를 봅니다.");
		default:
			System.out.println("외근을 나갑니다.");
			
//    break가 없어 case가 전부 실행됨
//		[현재 시간: 9시]
//		회의를 합니다.
//		업무를 봅니다.
//		외근을 나갑니다.
		}
	}
}

 

switch 문의 괄호에는 정수 타입(byte, char, short, int, long)과 문자열 타입(String) 변수를 사용할 수 있음

package ch04.sec03;

public class SwitchCharExample {
	public static void main(String[] args) {
		char grade = 'B';
		
		switch(grade) {
		case 'A':
		case 'a':
			System.out.println("우수 회원입니다.");
			break;
		case 'B':
		case 'b':
			System.out.println("일반 회원입니다.");
			break;
		default:
			System.out.println("손님입니다.");
			
		//일반 회원입니다.
		}
	}
}

 

Java12 이후부터 swtich 문에서 Expressions(표현식) 사용 가능

break 문을 없애는 대신, 화살표와 중괄호를 사용해 가독성이 좋아짐

package ch04.sec03;

public class SwitchExpressionsExample {
	public static void main(String[] args) {
		char grade = 'B';
		
		switch(grade) {
			case 'A', 'a' -> {
				System.out.println("우수 회원입니다.");
			}
			case 'B', 'b' -> {
				System.out.println("일반 회원입니다.");
			}
			default -> {
				System.out.println("손님입니다.");
			}
		}
		
		switch(grade) {
		case 'A', 'a' -> System.out.println("우수 회원입니다."); //중괄호 안에 실행문이 하나라면
		case 'B', 'b' -> System.out.println("일반 회원입니다."); //중괄호를 생략할 수 있음
		default -> System.out.println("손님입니다.");
		}
		
//		일반 회원입니다.
//		일반 회원입니다.
	}
}

 

Switch Expressions을 사용하면 스위치된 값을 변수에 바로 대입할 수도 있음

단일 값일 경우엔 화살표 오른쪽에 값을 기술하고

중괄호를 사용할 경우 yield 키워드로 값을 지정하면 되지만 defalut가 반드시 존재해야 함

타입 변수 = switch(grade) {
	case "값1" -> 변수값;
	case "값2" -> {
		...;
		yield 변수값;
	}
	default -> 변수값;
}

 

package ch04.sec03;

public class SwitchValueExample {
	public static void main(String[] args) {
		String grade = "B";
		
		//Java 11 이전 문법
		int score1 = 0;
		switch(grade) {
		case "A":
			score1 = 100;
			break;
		case "B":
			int result = 100-20;
			score1 = result;
			break;
		default:
			score1 = 60;
		}
		System.out.println(score1); //80
		
		//Java 12부터 가능
		int score2 = switch(grade) {
		case "A" -> 100;
		case "B" -> {
			int result = 100 - 20;
			//Java 13부터 가능
			yield result;
		}
		default -> 60;
		};
		System.out.println(score2); //80
	}
}

 

for 문

프로그램은 작성하다 보면 아래와 같이 똑같은 실행문을 반복적으로 실행해야 할 경우가 발생함

int sum = 0;
sum = sum + 1;
sum = sum + 2;
sum = sum + 3;
sum = sum + 4;
sum = sum + 5;
System.out.pringln("1~5까지의 합: " + sum);

 

이런 경우 for 문을 사용하면 코드를 획기적으로 줄일 수 있음

int sum = 0;
for(int i=1; i<=100; i++) { //100번 반복함
	sum = sum + 1;
}
System.out.pringln("1~100까지의 합: " + sum);

for(초기화식; 조건식; 증감식) {
	실행문;
}
//초기화식 후 조건이 true일 경우 실행문 실행, false일 경우 for문 종료
//조건식이 true여서 실행문을 실행한 후 증감식이 실행되고 다시 조건식 평가 반복

 

package ch04.sec04;

public class PrintFrom1To10Example {
	public static void main(String[] args) {
		for(int i=1; i<=10; i++) {
			System.out.print(i + " "); //1 2 3 4 5 6 7 8 9 10 
		}
	}
}

 

초기화식은 조건식과 실행문, 증감식에서 사용할 변수를 초기화하는 역할

초기화식, 증감식 등은 둘 이상 있을 수 있고 아래와 같이 쉼표(,)로 구분해서 작성

for (int i=0, j=100; i<=50 && j>=50; i++, j--) { ... }

 

초기화식에서 선언된 변수는 for 문 블록 안에서만 사용되는 로컬 변수

for 문을 벗어나서도 사용하고 싶다면 초기화식에서 변수를 선언하지 말고 for 문 이전에 선언해야 함

int i; //for 문 이전에 변수 i 선언
for(i=1; i<=100; i++) { ... }
System.out.printlm("최종 i값: " + i); //for 문을 벗어나서 i를 사용

 

package ch04.sec04;

public class SumFrom1To100Example {
	public static void main(String[] args) {
		int sum = 0; //합계 변수
		int i; //카운터 변수
		
		for(i=1; i<=100; i++) {
			sum += i;
		}
		
		System.out.println("1~" + (i-1) + "의 합: " + sum);
		//1~100의 합: 5050
	}
}

 

for 문을 작성할 때 주의할 점은 초기화식에서 부동 소수점을 쓰는 float 타입을 사용하지 말아야 한다는 것

package ch04.sec04;

public class FloatCounterExample {
	public static void main(String[] args) {
		for(float x=0.1f; x<=1.0f; x+=0.1f) {
			System.out.println(x);
			
//			0.1
//			0.2
//			0.3
//			0.4
//			0.5
//			0.6
//			0.70000005
//			0.8000001
//			0.9000001
//			부동 소수점 방식의 float 타입은 연산 과정에서 정확히 0.1을 표현하지
//			못하기 때문에 증감식에서 x에 더해지는 실제 값은 0.1보다 약간 클 수 있다
//			따라서 최종 반복 횟수는 9번이 된다
		}
	}
}

 

for 문은 또 다른 for 문을 내포할 수 있는데, 이를 중첩된 for 문이라고 함

이 경우 바깥 for 문이 한번 실행할 때마다 중첩된 for 문은 지정 횟수만큼 반복하고 다시 바깥 for 문으로 돌아감

package ch04.sec04;

public class MultiplicationTableExample {
	public static void main(String[] args) {
		for(int m=2; m<=9; m++) { //2~9단
			System.out.println("=== " + m + "단 ===");
			for(int n=1; n<=9; n++) {
				System.out.println(m + " x " + n + " = " + (m*n));
			}
		}
	}
}

 

while문

for 문이 정해진 횟수만큼 반복한다면, while 문은 조건식이 true일 경우에 계속해서 반복하고, false가 되면 반복을 멈추고 while 문을 종료함

while(조건식) {
	실행문;
}
//조건식을 평가해 결과가 true면 실행문을 실행하고 다시 조건식을 평가
//또 true라면 계속 반복 false라면 while문을 종료함

 

package ch04.sec05;

public class PrintFrom1To10Example {
	public static void main(String[] args) {
		int i = 1;
		while(i<=10) {
			System.out.print(i + " "); //1 2 3 4 5 6 7 8 9 10 
			i++;
		}
	}
}

 

package ch04.sec05;

public class SumFrom1To100Example {
	public static void main(String[] args) {
		int sum = 0; //합계 변수
		
		int i = 1; //카운터 변수
		
		while(i<=100) {
			sum += i;
			i++;
		}
		
		System.out.println("1~" + (i-1) + "의 합: " +sum);
		//1~100의 합: 5050
	}
}

 

package ch04.sec05;

import java.util.Scanner;

public class KeyControlExample {
	public static void main(String[] args) throws Exception{
		Scanner scanner = new Scanner(System.in); //Scanner 생성
		boolean run = true; //while 문의 조건식을 위한 변수 선언
		int speed = 0;
		
		while(run) {
			System.out.println("=====");
			System.out.println("1. 증속 | 2. 감속 | 3. 중지");
			System.out.println("=====");
			System.out.println("선택: ");
			
			String strNum = scanner.nextLine(); //키보드 입력 내용을 읽음
			
			if(strNum.equals("1")) {
				speed++;
				System.out.println("현재 속도= " + speed);
			} else if(strNum.equals("2")) {
				speed--;
				System.out.println("현재 속도= " + speed);
			} else if(strNum.equals("3")) {
				run = false; //while문의 조건식을 false로 만듦
			}
		}
		
		System.out.println("프로그램 종료");
	}
}

 

do-while 문

do-while 문은 조건식에 의해 반복 실행한다는 점에서 while 문과 동일

while 문은 시작할 때부터 조건식을 평가하여 블록 내부를 실행할지 결정하지만,

do-while 문은 블록 내부를 먼저 실행시키고, 실행 결과에 따라 반복 실행을 계속할지 결정함

do-while 문 작성 시 while() 뒤에 반드시 세미콜론(;)을 붙여야 함

do {
	실행문;
} while (조건식);
//실행문을 실행한 후 조건식을 평가해 결과가 true이면 반복실행
//조건식의 결과가 false이면 do-while 문을 종료함

 

package ch04.sec06;

import java.util.Scanner;

public class DoWhileExample {
	public static void main(String[] args) {
		System.out.println("메시지를 입력하세요");
		System.out.println("프로그램을 종료하려면 q를 입력하세요");
		
		Scanner scanner = new Scanner(System.in); //Scanner 생성
		String inputString;
		
		do {
			System.out.println(">");
			inputString = scanner.nextLine(); //키보드로부터 읽기
			System.out.println(inputString);
		} while(! inputString.equals("q")); //입력 내용이 q가 아니라면 계속 반복
		
		System.out.println();
		System.out.println("프로그램 종료");
	}
}

 

break 문

break 문은 반복문인 for 문, whlie 문, do-while 문을 실행 중지하거나 조건문인 switch 문을 종료할 때 사용함

대개 if 문과 같이 사용되어 조건식에 따라 for 문과 while 문을 종료함

package ch04.sec07;

public class BreakExample {
	public static void main(String[] args) throws Exception{
		while(true) {
			int num = (int)(Math.random()*6) + 1; //주사위 1~6 뽑기
			System.out.println(num);
			if(num == 6) {
				break; //6이 나오면 while문 종료
			}
		}
		System.out.println("프로그램 종료");
	}
}

 

만약 반복문이 중첩되어 있을 경우 break 문은 가장 가까운 반복문만 종료하고 바깥쪽 반복문은 종료시키지 않음

바깥쪽 반복문까지 종료시키려면 바깥쪽 반복문에 이름(레이블)을 붙이고, ‘break 이름;’을 사용

package ch04.sec07;

public class BreakOutterExample {
	public static void main(String[] args) throws Exception{
		Outter: for(char upper='A'; upper<='Z'; upper++) {
			for(char lower='a'; lower<='z'; lower++) {
				System.out.println(upper + "-" + lower);
				if(lower=='g') {
					break Outter;
				}
			}
		}
		System.out.println("프로그램 실행 종료");
		
//		A-a
//		A-b
//		A-c
//		A-d
//		A-e
//		A-f
//		A-g
//		프로그램 실행 종료
	}
}

 

continue 문

continue 문은 반복문인 for 문, while 문, do-while 문에서만 사용되는데, 블록 내부에서 continue 문이 실행되면 for 문의 증감식 또는 while 문, do-while 문의 조건식으로 바로 이동함

continue 문은 반복문을 종료하지 않고 계속 반복을 수행한다는 점이 break 문과 다름

특정 조건을 만족하는 경우 continue 문을 실행해서 그 이후의 문장을 실행하지 않고 다음 반복으로 넘어감

package ch04.sec08;

public class ContinueExample {
	public static void main(String[] args) throws Exception{
		for(int i=1; i<=10; i++) {
			if(i%2 != 0) { //홀수인 경우, 2로 나눈 나머지가 0이 아닌 경우
				continue; //증감식으로 바로 이동, 짝수만 출력됨
			}
			System.out.print(i + " "); //2 4 6 8 10 
		}
	}
}

 

연습문제

package ch04;

public class Test1 {
	public static void main(String[] args) {
		//아래의 switch 문을 Expression(표현식)으로 변경하기
		String grade = "B";
		
		int score1 = 0;
		switch(grade) {
			case "A":
				score1 = 100;
				break;
			case "B":
				int result = 100 - 20;
				score1 = result;
				break;
			default:
				score1 = 60;
		}
		System.out.println(score1); //80
		
		//Expression(표현식)으로 변경
		int score2 = switch(grade) {
			case "A" -> 100;
			case "B" -> {
				int result = 100 - 20;
				yield result;
			}
			default -> 60;
		};
		
		System.out.println(score2); //80
	}
}

 

package ch04;

public class Test2 {
	public static void main(String[] args) {
		//for문을 이용해 1~100까지 정수 중 3의 배수의 총합을 출력하기
		int sum = 0;
		
		for(int i=1; i<=100; i++) {
			if(i%3 == 0) {
				sum += i;
			}
		}
		
		System.out.println(sum); //1683
	}
}

 

package ch04;

public class Test3 {
	public static void main(String[] args) {
//		while 문과 Math.random() 메소드를 이용해 주사위 던졌을 때 나오는 눈을
//		(눈1, 눈2) 형태로 출력하고, 합이 5일때만 실행을 멈추는 코드
		while(true) {
			int num1 = (int)(Math.random()*6) + 1;
			int num2 = (int)(Math.random()*6) + 1;
			System.out.print("(" + num1 + ", " + num2 + ")");
			System.out.println();
			
			if(num1 + num2 == 5) {
				break;
			}
		}
	}
}

 

package ch04;

public class Test4 {
	public static void main(String[] args) {
//		중첩된 for 문을 이용해 방정식 4x + 5y = 60의 모든 해를 구해서
//		(x, y) 형태로 출력. 단, x와 y는 10 이하의 자연수
		for(int x=1; x<=10; x++) {
			for(int y=1; y<=10; y++) {
				if((4*x + 5*y) == 60) {
					System.out.println("(" + x + ", " + y + ")");
				}
			}
		}
	}
}

 

package ch04;

public class Test5 {
	public static void main(String[] args) {
//		for문을 이용해 아래의 문자를 출력
//		*
//		**
//		***
//		****
//		*****
		for(int i=0; i<5; i++) {
			for(int j=0; j<=i; j++) {
				System.out.print("*");
				if(i == j) {
					System.out.println();
				}
			}
		}
	}
}

 

package ch04;

import java.util.Scanner;

public class Test6 {
	public static void main(String[] args) {
//		while 문과 Scanner의 nextLine() 메소드를 이용해 키보드로부터
//		입력된 데이터로 예금, 출금, 조회, 종료 기능을 제공하는 코드 작성
		Scanner scanner = new Scanner(System.in);
		boolean run = true;
		int balance = 0;
		
		while(run) {
			System.out.println("---------------");
			System.out.println("1. 예금 | 2. 출금 | 3. 잔고 | 3. 종료");
			System.out.println("---------------");
			System.out.print("선택> ");
			
			int menuNum = scanner.nextInt();
			
			switch(menuNum) {
				case 1 -> {
					System.out.print("예금액> ");
					balance += scanner.nextInt();
				}
				case 2 -> {
					System.out.print("출금액> ");
					balance -= scanner.nextInt();
				}
				case 3 -> {
					System.out.println("잔고> " + balance);
				}
				case 4 -> {
					run = false;
				}
			}			
		}
		System.out.println("프로그램 종료");
	}
}

 

package ch04;

public class test7 {
	public static void main(String[] args) {
//		**** 
//		**** 
//		**** 
		for(int i=0; i<3; i++) {
			for(int j=0; j<4; j++) {
				System.out.print("*");
			}
			System.out.println(" ");
		}
		System.out.println("=====");
		
//		*
//		**
//		***
//		****
		for(int i=0; i<4; i++) {
			for(int j=0; j<=i; j++) {
				System.out.print("*");
			}
			System.out.println();
		}
		System.out.println("=====");
		
//		    *
//		   **
//		  ***
//		 ****
		for(int i=1; i<5; i++) {
			for(int j=4; j>0; j--) {
				if(i < j) {
					System.out.print(" ");
				} else {
					System.out.print("*");
				}
			}
			System.out.println();
		}
		System.out.println("=====");
		
//		    *
//		   ***
//		  *****
//		 *******
		for(int i=0; i<4; i++) {
			for(int j=0; j<3-i; j++) {
				System.out.print(" ");
			}
			for(int j=0; j<2*i+1; j++) {
				System.out.print("*");
			}
			System.out.println();
		}
		System.out.println("=====");
		
//		    *
//		   ***
//		  *****
//		 *******
//		  *****
//		   ***
//		    *
		for(int i=0; i<4; i++) {   
            for(int j=0; j<3-i; j++) {
                System.out.print(" ");
            }
            for(int j=0; j<i*2+1; j++) { //나머지 별 한방에채우기.
                System.out.print("*"); 
            }
            System.out.println();
        }
        for(int i=3; i>0; i--) {
            for (int j=4; j>i; j--) {
                System.out.print(" ");
            }
            for (int j=0; j<i*2-1; j++) {
                System.out.print("*"); 
            }
            System.out.println();
		}
	}
}

'공부기록 > 자바' 카테고리의 다른 글

Chapter 06. 클래스  (0) 2022.12.18
Chapter 05. 참조 타입  (0) 2022.11.23
Chapter 03. 연산자  (0) 2022.11.21
Chapter 02. 변수와 타입  (0) 2022.11.21
Chapter 01. 자바 시작하기  (0) 2022.11.19

댓글