[Java] 제어문
프로그램의 실행 순서에 변화를 주고자 할 때 사용하는 것이 제어문이다. 조건에 따라 실행되는 명령이 달라지게 만들기 위해 사용하는 조건문, 필요한 만큼 반복적으로 특정 코드를 실행시키게 하는 반복문이 그 예이다.
조건문
자바에서 조건문을 사용하려면 if문, 조건 연산자, switch문을 사용하면 된다. (조건 연산자는 연산자 페이지의 “조건 연산자” 챕터에서 이미 다룬 바 있으므로 해당 문서 참고)
if문
기본 형태는 다음과 같다.
if (조건식) {
// 조건이 true일 때 실행할 내용.
}
if (조건식) {
// 조건식이 true일 때 실행할 코드.
} else {
// 조건식이 false일 때 실행할 코드.
}
if (조건식1) {
// 조건식1이 true일 때 실행할 코드.
} else if (조건식2) {
// 조건식2가 true일 때 실행할 코드.
} else {
// 위 조건식 모두 false일 때 실행할 코드.
}
else if 키워드는 여러 번 사용할 수 있다.
파이썬에서는 elif 라는 키워드가 있는 반면, 자바에는 그런 키워드가 따로 없어서 혹시라도 elseif 처럼 두 키워드를 붙여서 사용하지 않도록 유의한다.
괄호 안의 조건식에는 주로 비교 연산식 또는 여러 조건의 경우 비교 연산식들로 묶인 논리합, 논리 곱등의 논리 연산식이 사용되며, 연산 결과가 true 또는 false 둘 중 하나만을 반환하는 boolean 자료형이면 된다.
다음은 if문을 이용하여 주어진 숫자의 짝수 여부를 판별하는 예제이다.
public class IfExample {
public static void main(String[] args) {
int num = 10;
if (num % 2 == 0) {
System.out.println("짝수");
} else {
System.out.println("홀수");
}
}
}
짝수
중괄호 안의 코드가 만약 한 줄이라면 중괄호를 생략할 수 있으며, 그 한 줄이 짧다면 if (조건식) 의 옆에 작성할 수도 있다.
public class IfExample {
public static void main(String[] args) {
int num = 11;
if (num % 2 == 0)
System.out.println("짝수");
else
System.out.println("홀수");
if (num % 2 == 1) System.out.println("홀수");
else System.out.println("짝수");
}
}
홀수
홀수
중괄호 내 코드가 한 줄일 경우, 중괄호를 그대로 작성할지, 아니면 중괄호를 생략할지, 조건식과 함께 한 줄로 작성할 것인지는 코드 분량, 가독성 등을 따져서 선택하면 되겠다.
switch문
switch문은 조건식에서 나올 수 있는 여러 가지 경우의 수에 대해 각각의 경우에 특정 코드를 처리할 수 있게 하는 제어문이다.
switch문의 구조는 다음과 같다.
switch(조건식) {
case 값1:
// 코드 1
break;
case 값2:
// 코드 2
break;
default:
// 그 어떤 case도 만족하지 않을 경우 실행할 코드.
}
조건식의 연산 결과로 나올 반환값의 경우의 수가 여러 개일 경우, 각각 예상되는 반환값을 case 키워드 뒤에 적고, 그 아래에 해당 case일 경우 실행할 코드를 작성한다. 해당 case는 원하는 만큼 작성할 수 있다. 그리고 만약 코드 실행 후 다음 case문이 실행되는 것을 원치 않는다면 break문을 해당 case 코드 내 맨 마지막에 작성해줘야 한다. 그러면 switch문을 빠져나간다. break문을 쓰지 않는다면 다음 case문까지 실행된다.
default문은 if문의 else 키워드와 같은 기능을 한다. 즉, 조건식의 반환값이 위의 어떤 case에도 만족되지 않을 때를 처리하기 위한 코드를 작성할 때 쓰인다.
다음은 switch문을 이용하여, 학생의 점수에 따른 등급을 매겨 이를 출력하는 코드이다.
public class SwitchExample {
public static void main(String[] args) {
int myScore = 100;
char myGrade;
switch(myScore / 10) {
case 10:
case 9:
myGrade = 'A';
break;
case 8:
myGrade = 'B';
break;
case 7:
case 6:
case 5:
myGrade = 'C';
break;
case 4:
case 3:
case 2:
myGrade = 'D';
break;
default:
myGrade = 'F';
}
System.out.println(myGrade);
}
}
A
위 예제에서 myScore의 값을 0에서 100 사이의 정수를 아무거나 대입하고 테스트해보면 myGrade에는 어떤 문자가 대입될 지 확인할 수 있다.
위 예제에서 myScore는 100이고, 이를 switch의 조건식에서 만나니 조건식의 결과가 10인 것을 추측할 수 있다. 이는 여러 case들 중에서 case 10을 만족한다. 그런데 해당 case의 코드가 존재하지 않는다. 그러면 바로 아래의 case로 넘어간다. case 9에는 코드가 존재하므로 해당 코드가 실행된다. 즉, myGrade = ‘A’;
가 할당된다. 그 다음 줄에 break문이 있으므로 바로 switch문을 빠져나가 해당 변수에 할당된 값인 ‘A’가 그대로 출력된다.
참고로, if문의 조건식에는 10 < num && num < 20
과 같이 숫자의 범위를 체크하는 조건식을 사용할 수 있지만, switch문의 case 뒤에는 비교 연산자를 이용하여 숫자 범위를 지정하는 것이 불가능하다. 예를 들어 case 1 < num && num < 2
와 같은 코드는 불가능하다. 대신 case 키워드 뒤에는 switch 조건식에서 나올 겻으로 예상되는 결과값과 동일한 값을 입력해야 한다.
대신 위 에제에서는 switch문을 사용했음에도 사실상 숫자 범위를 지정하였다. 그것은 바로 break;문 없이 case10: case9: 코드를 연속적으로 작성한 것이다. case 7일 경우와 case 6, case 5일 경우 모두 myGrade = ‘C’
라는 같은 코드를 처리하게 되므로 사실상 if (5 <= myScore / 10 && myScore / 10 <= 7)
과 같은 결과를 낸다.
참고로 위 예제 2-1을 if문으로 재구성하면 다음과 같다.
public class SwitchIf {
public static void main(String[] args) {
// SwitchExample.java 내 내용을 if문으로 재구성함.
int myScore = 100;
char myGrade;
int q = myScore / 10;
if (9 <= q && q <= 10) {
myGrade = 'A';
} else if (q == 8) {
myGrade = 'B';
} else if (5 <= q && q <= 7) {
myGrade = 'C';
} else if (2 <= q && q <= 4) {
myGrade = 'D';
} else {
myGrade = 'F';
}
System.out.println(myGrade);
}
}
A
자바 7 버전 이후로는 case 뒤에 case “가나다”와 같이 문자열도 사용할 수 있다고 한다.
반복문
특정 조건이 성립하는 동안 특정 코드를 반복적으로 실행시키고자 할 때 쓰이는 것이 반복문이다. 자바에서의 반복문은 for, while, do~while문 이렇게 3가지 반복문이 존재한다.
for문
기본 구조는 다음과 같다.
for (초기식; 조건식; 증감식) {
// 반복 처리할 코드.
}
다음은 for문을 이용하여 1부터 n까지 연속되는 자연수들을 모두 더한 값을 알아내는 에제이다.
public class For {
public static void main(String[] args) {
int total = 0;
int n = 100;
// for문 사용 예1. 1부터 100까지 연속된 자연수들을 모두 더하기.
for (int i = 1; i <= n; i++) {
total += i;
}
System.out.println(total);
// for문 사용 예2. 초기식을 생략하고, 증감식 자리에 연산식을 사용.
int j = 1;
int total2 = 0;
for(; j <= n; j = j + 1) {
total2 += j;
}
System.out.println(total2);
}
}
5050
5050
위 예제에서 볼 수 있듯, for문 내 초기식이 이미 이전에 정의된 경우 생략할 수 있다. 또한, 증감식을 생략하거나 증감식 대신 어떠한 연산식을 사용해도 된다. 증감식을 생략하면 for문 중괄호 내부에서 증감식을 따로 작성하고, 필요하면 조건문과 break문을 적절히 활용하여 특정 조건일 경우 for문을 빠져나오게끔 설계하면 된다. 만약 증감식을 생략했는데 for문 중괄호 내에서도 증감식이 없을 경우 무한루프에 빠질 수 있으니 주의.
while문
while문의 기본 구조는 다음과 같다.
while(조건식) {
// 반복 실행할 코드.
}
for문을 포함한 모든 반복문은 언젠가는 빠져나가야 하므로 증감식과 같이 특정 조건을 만족하여 반복문을 빠져나갈 수 있게 하는 종료식이 필요하다. while문의 경우, while ((i++) < 10)
과 같이 증감식을 조건식 안에 작성할 수도 있고, 아니면 보통 중괄호 안에 증감식을 작성하고, 필요에 따라 if문과 break문을 활용하여 특정 조건이 되면 반복문을 모두 반복하지 않고 중간에 빠져나가게끔 설계할 수도 있다.
다음은 while문을 이용하여 1부터 n까지의 자연수 중 오로지 소수(prime number)들만 더한 값을 출력하는 예제이다.
public class While {
public static void main(String[] args) {
// 1부터 n까지의 자연수 중, 소수만을 더하는 프로그램.
int n = 100;
int total = 0;
int i = 1;
int root;
boolean isPrime;
while(i <= n) {
// 해당 숫자가 소수인지 판별.
root = (int)Math.sqrt(i);
isPrime = false;
for (int j = 2; j <= root; j++) {
if (i % j == 0) {
isPrime = false;
break;
} else {
isPrime = true;
}
}
if (i == 2 || i == 3) {
isPrime = true;
}
if (isPrime) {
total += i;
System.out.println(i);
}
i++;
}
System.out.println("결과 : " +total);
}
}
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
59
61
67
71
73
79
83
89
97
결과 : 1060
do ~ while문
do {
// 실행할 코드.
} while(조건문);
do ~ while문도 반복문이지만, 먼저 조건이 맞는지 확인하고 반복문 내 코드를 실행시켰던 for, while문과 달리, do ~ while문은 일단 한 번은 조건 확인 없이 무조건 실행시키고, 그 이후부터는 조건식을 확인하는 방식의 반복문이다.
lable과 중첩된 반복문으로부터 모두 빠져나가기
중첩 반복문을 사용했을 때, 가장 안쪽의 반복문 내에서 특정 조건을 만족시켜 중첩 반복문 자체를 빠져나가게끔 하고자 한다면 가장 바깥쪽의 반복문 앞에 lable을 지정한 후, break 키워드 뒤에 해당 lable 이름을 지정하면 된다.
다음은 2단부터 n단까지의 곱셈 결과를 모두 더하는 예제이다. 이 때, 두 수의 곱셈값이 n을 넘으면 반복문을 중단하고 바로 결과값을 출력할 수 있게끔 설계한 예제이다.
public class LableBreak {
public static void main(String[] args) {
// 2부터 n단 까지의 곱셈들을 모두 더하는 프로그램.
// 만약 두 숫자의 곱셈 결과가 n을 넘어가면 반복문을 중단하게끔 함.
int n = 100;
int total = 0;
escape: for(int i = 2; i <= n; i++) {
for(int j = 1; j <= 9; j++) {
total += i * j;
if ((i * j) > n) {
System.out.printf("마지막 곱셈 : %d * %d = %d\n", i, j, i * j);
break escape;
}
}
}
System.out.println(total);
}
}
마지막 곱셈 : 12 * 9 = 108
3465
위 예제를 살펴보면, 가장 바깥쪽의 반복문 왼쪽에 escape: 라고 lable을 지정하였으며, 가장 안쪽의 반복문에 조건문과 함께 그 안에 break escape;라고 작성하였다. 그 결과, if문의 조건식을 만족하면 그 즉시 안쪽의 반복문 뿐만 아니라 escape라는 lable이 지정된 가장 바깥쪽의 반복문까지 빠져나가 반복문이 완전히 중단된다. 만약 이러한 lable 기능이 없었다면 가장 안쪽 반복문 내부에 break문을 사용해도 그 반복문만 빠져나갈 뿐, 그 바깥의 반복문까지 중단시키지는 못했을 것이다.
References
[1] 이재환, “이재환의 자바 프로그래밍 입문”, (골든래빗, 2021)
This content is licensed under
CC BY-NC 4.0
댓글남기기