4. 조건문과 반복문
제어문 : 프로그램의 흐름을 바꾸는 역할을 하는 문장들. 제어문에는 조건문과 반복문이 있다.
조건문
조건문은 프로그램의 조건에 따라 문장이 수행되도록 한다.
if
가장 기본적인 조건문으로 조건식과 괄호로 구성된다.
if (조건식) {
수행문장
}
ex)
int a = 0
if (a == 0){
System.out.printf("a는 0 입니다.");
}
조건식은 일반적으로 비교연산자 및 논리연산자로 구성된다. 아래에 샘플로 몇 가지를 살펴보자.
90 <= x && x <= 100 : 정수 x가 90이상이고, 100 이하인 경우. 정수 x의 값이 90~100 인 경우 참.
90 >= x || x >= 100 : 정수 x가 90이하거나, 100 이상인 경우. 정수 x의 값이 91~99인 경우 거짓.
str.equals("yes") : 문자열 str의 내용이 "yes"일 경우 참.(대소문자 구분)
str.equalsIgnoreCase("yes") : 문자열 str의 내용이 "yes"일 경우 참.(대소문자 구분안함)
이러한 조건식 중 실수하기 쉬운 것이 등가비교 연산자 "=="를 "="로 사용하는 것이며, "=="와 "="가 틀린 이유는 "="는 참/거짓 이 될 수 없기 때문이다. 아래의 샘플로 확인한다.
(참)
변수 x 가 10인 경우, 참 또는 거짓으로 확인할 수 있다.
if (x == 10){
수행문장
}
(거짓)
변수 x는 10, 참 또는 거짓으로 확인할 수 없다.
if (x = 10){
수행문장
}
{} (블럭)
{}를 이용해서 여러 문장들을 하나의 단위로 묶어줄 수 있는데, 이것을 블럭이라고 한다. 블럭은 '{'로 시작해서 '}'로 끝나며, 마지막에는 일반 문장에서 붙이는 ';'를 붙이지 않는다.
만약 수행문장이 한 문장일 경우에는 블럭 없이 사용할 수 있지만, 혹시 나중에 수행문장이 추가되거나 조건문의 수행문장임을 표현하기 위해서라도 블럭을 사용하는 것이 좋다.
(일반문장)
System.out.printf("테스트 입니다.");
(O)
if (조건식) {
System.out.printf("테스트 입니다.");
}
(X)
if (조건식) {
System.out.printf("테스트 입니다.");
};
(O)
if (조건식)
System.out.printf("테스트 입니다.");
if (조건식) System.out.printf("테스트 입니다.");
(X)
if (조건식)
System.out.printf("테스트 입니다."); <- 조건문의 수행문장
System.out.printf("테스트 입니다."); <- 조건문과는 상관없는 문장.
if-else문
if-else문은 기본 if문에서 if의 조건식에 부합되지 않는 경우 else의 수행문장 또는 블럭 내 수행문장(들)을 수행한다.
(기본 if문)
변수 x가 10인 경우 블럭 -1 문장을 수행하지만, 아닌 경우에는 -2 문장만 수행한다.
if (x == 10){
System.out.printf("x는 10입니다."); -1
}
System.out.printf("테스트 입니다."); -2
(if-else문)
변수 x가 10인 경우 블럭 -1 문장을 수행하지만, 변수 x가 10이 아닌 경우 즉 조건식이 참이 아닌 나머지 모든 경우에 -3 문장을 수행하고, 이 후 -2 순으로 문장을 수행한다.
if (x == 10){
System.out.printf("x는 10입니다."); -1
} else {
System.out.printf("x는 10이 아닙니다."); -3
}
System.out.printf("테스트 입니다."); -2
if-else if문
만약 조건문으로 처리해야할 조건이 하나(if문), 둘(if-else문)이 아닌 셋 이상이라면 if-else if문을 사용한다.
기본 구조는 아래와 같이 if, else if, else 로 구성되며, else는 생략 가능하다.
다만 else를 생략할 경우 if, else if 조건식에 부합되지 않는 경우에는 수행되는 문장이 없다.
if (조건식 1){
} else if (조건식 2){
} else if (조건식 3){
} else {
}
중첩 if문
if문 블럭내에 다른 if문을 포함시키는 것.
if (조건문) {
if (조건문) {
수행문장
} else {
수행문장
}
}
switch
if문의 경우 조건식을 통해 참/거짓 이라는 두 가지 결과밖에 처리할 수 없기 때문에, 다양한 경우의 수를 처리하기 위해서 switch문을 사용한다.
switch (조건식) {
case 값1 :
수행문장
break;
case 값2 :
수행문장
break;
case 값3 :
수행문장
break;
default :
수행문장
}
switch (x >= 10) {
case 10 :
System.out.printf("x는 10 입니다.");
break;
case 11 :
System.out.printf("x는 11 입니다.");
break;
case 12 :
System.out.printf("x는 12 입니다.");
break;
default :
System.out.printf("x는 13 이상 입니다.");
}
switch문 제약조건
- switch문의 조건식 결과는 정수 또는 문자열이어야 한다.
- case문의 값은 정수 상수만 가능하며, 중복되지 않아야 한다.
switch (x >= 10) {
case 10 :
System.out.printf("x는 10 입니다.");
break;
case "YES" :
System.out.printf("x는 문자열 상수 입니다.");
break;
case yes : <- 문자열 상수로 에러 발생
System.out.printf("x는 입니다.");
break;
default :
System.out.printf("x는 13 이상 입니다.");
}
switch문 -> if문
보통 switch문은 if문으로 변환이 가능하지만, 반대의 경우에는 변환이 되지 않는 경우가 많다.
(switch문을 if문으로 변환하는 샘플)
switch (x >= 10) {
case 10 :
System.out.printf("x는 10 입니다.");
break;
case 11 :
System.out.printf("x는 11 입니다.");
break;
case 12 :
System.out.printf("x는 12 입니다.");
break;
default :
System.out.printf("x는 13 이상 입니다.");
}
if (x == 10) {
System.out.printf("x는 10 입니다.");
} else if (x == 11) {
System.out.printf("x는 11 입니다.");
} else if (x == 12) {
System.out.printf("x는 12 입니다.");
} else {
System.out.printf("x는 13 이상 입니다.");
}
switch문 중첩
if문과 마찬가지로 switch문도 중첩이 가능하다.
char regNo
char gender
regNo = "011231-1111222";
gender = regNo.charAt(7);
swich (gender) {
case '1':
case '3':
switch (gender) {
case '1':
System.out.printf("2000년 이 전 출생자 입니다.");
break;
case '3':
System.out.printf("2000년 이 후 출생자 입니다.");
}
break;
case '2':
case '4':
switch (gender) {
case '2':
System.out.printf("2000년 이 전 출생자 입니다.");
break;
case '4':
System.out.printf("2000년 이 후 출생자 입니다.");
}
break;
default:
System.out.printf("잘못 입력 하셨습니다.")
}
2. 반복문 - for, while, do-while
2.1 for문
a. 기본적인 사용
for(int i=1; i<=5; i++){
System.out.println("I can do it.");
}
for(초기화; 조건식; 증감식){
// 조건식이 true 일때 코드 실행
}
b. 두개의 변수 사용 (comma 사용)
for(int i=1, j=10; i<=10; i++, j--;){
....
}
c. 초기화, 조건식 증감식 생략 조건식이 항상 true로 간주되어 무한반복되므로 {} 블럭안에 if를 넣어 특정조건이면 빠져나오도록 해야한다. 안그럼...
for (;;){
....
}
d. Syntex 기본적으로 {} 사용
for(int i=2; i<=9; i++){
for(int j=1; j<=9; j++){
System.out.printf("%d x %d = %d%n", i, j, i*j);
}
}
{} 블럭안에 코드가 한줄이면 {} 생략가능
for(int i=2; i<=9; i++){
for(int j=1; j<=9; j++)
System.out.printf("%d x %d = %d%n", i, j, i*j);
}
결과적으로는 아래와 같이 사용가능
for(int i=2; i<=9; i++)
for(int j=1; j<=9; j++)
System.out.printf("%d x %d = %d%n", i, j, i*j);
e. 향상된 for문(enhanced for statement)
for( 타입 변수명 : 배열 또는 컬렉션 {
// 반복할 문장
}
예를 들어 배열을 iterate 할 경우 기존의 for문과 enhanced된 for문을 비교하면 다음과 같다.
int[] arr = {10,20,30,40,50};
for (int i=0; i< arr.length; i++){
System.out.println(arr[i]);
}
int[] arr = {10,20,30,40,50};
for (int tmp : arr){
System.out.println(tmp);
}
2.2 while문
a. 기본적인 사용
while(조건식){
// 조건식이 true일경우 실행할 코드
}
for(int i=1; i<=5; i++){
System.out.println(i);
}
same as
int = 1;
while(i<=5) {
System.out.println(i);
i++;
}
for (;;){
....
}
same as
while(true){
....
}
[예제 1]
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 < 2000000000; j++) {
;
}
}
System.out.println("GAME OVER");
}
}
[예제 1 Output]
자, 이제 카운트 다운을 시작합니다.
10
9
8
7
6
5
4
3
2
1
0
GAME OVER
여기서 아래 코드를 보면
for(int j = 0; j < 2000000000; j++) {
;
}
아무것도 하지 않고 2,000,000,000 돌때까지 println의 실행을 늦추는것
블럭내 문장이 한줄이므로 {} 생략하면 다음과 같이 표기 가능
for(int j = 0; j < 2000000000; j++);
또는
for(int j = 0; j < 2000000000; j++){}
그런데 다음과 같이 작성한 경우, 어떤 output이 예상되는가?
for(int i = 0; i < 10; i++);
{
System.out.println("i=" + i);
}
** 빈문장을 ';' 10번 반복한 후 "i=11" 츨력
2.3 do-while문
while문의 변형으로 조건식이 {}을 먼저 수행한 후에 평가된다 while문은 {} 내에 코드가 한번도 실행되지 않을 경우가 있으나, do-while문의 경우는 최소 한번은 실행된다. 많이 쓰이지는 않으나, 다음 [예제 1]과 같이 반복적인 입력을 받아 처리를 해야 할 경우 유용하다.
a. 기본 사용
do {
// 먼저 코드 실행 후 조건식 검토
} while(조건식);
[예제 1]
class FlowEx28
{
public static void main(String[] args)
{
int input=0;
int answer=0;
answer = (int)(Math.random()*100) + 1;
Scanner scanner = new Scanner(System.in);
do {
System.out.print("1과 100사이의 정수를 입력하세요>.");
String tmp = scanner.nextLine();
input = Integer.parseInt(tmp);
if(input > answer){
System.out.print("더 작은 수로 다시 시도해보세요.");
} else if(input < answer){
System.out.print("더 큰 수로 다시 시도해보세요.");
}
} while(input != answer);
System.out.print("정답입니다.");
}
}
2.4 break문
a. 기본사용 반복문에서의 break는 자신이 포함된 가장 가까운 반복문을 벗어나는데 쓰인다. 아래 예제는 이전 for문에서 보았던 for(;;) {} 형태의 반복문인데 이경우 조건문과 break가 반드시 같이 사용되어야 한다.
class FlowEx30
{
public static void main(String[] args)
{
int sum = 0;
int i = 0;
while(true){
if(sum > 100){
break; // -->while {}내의 코드 실행하지 않고 while 문을 완젼히 벗어난다.
}
++i;
sum +=i;
}
System.out.println("i=" + i);
System.out.println("sum=" + sum);
}
}
2.5 continue문
continue 문은 반복문내에서 {} 내의 continue 이후 코드를 실행하지 않고 다음 반복을 계속 수행할때 쓰이며, 보통 if 문과 함께 특정 조건을 만족하는 경우 다음 반복으로 넘어가서 진행하도록 한다 [예제 1 ]
class FlowEx31
{
public static void main(String[] args)
{
for(int i=1; i<=10; i++){
if(i%3)
continue;
System.out.println(i);
}
}
}
[예제 1 Output] 3의 배수만 제외하고 프린트
1
2
3
5
7
8
10
2.5 이름 붙은 반복문
break 문은 근접한 하나의 반복문만 벗어날 수 있기 때문에 여러개의 반복문이 중첩된 경유 break문으로 중첩 반복문을 완전히 벗어날 수 없다. 이때, 중첩 반복문 앞에 이름을 붙이고, break문과 continue문에 이름을 지정해 하나 이상의 반복문을 벗어나거나 반복을 건너뛸 수 있게 한다.
[예제 1]
class FlowEx33
{
public static void main(String[] args)
{
for(int i=2; i<=9; i++){
for(int j=1; j<=9; j++){
if(j==5)
break;
System.out.printf(i + "*" +j +"=" + i*J);
}
}
}
}
[예제 1 Output]
2*1=2
2*2=4
2*3=6
2*4=8
3*1=3
3*2=6
3*3=9
3*4=12
..
..
[예제 2]
class FlowEx33
{
public static void main(String[] args)
{
Loop1 : for(int i=2; i<=9; i++){
for(int j=1; j<=9; j++){
if(j==5)
break Loop1;
System.out.printf("%d x %d = %d%n", i, j, i*j);
}
}
}
}
[예제 2 Output]
2*1=2
2*2=4
2*3=6
2*4=8