2011년 4월 26일 화요일

자바의 제어문(for)

자바의 제어문 중에서도 가장 많이 쓰이는 것 중에 하나가 반복문이다. 자바에서 반복을 행하는 for문은 소스를 볼때마다 없으면 이상할 정도로 자주 보게 될것인데 당연하지만 같은 내용을 두번 세번 만들 필요없이 한번만 고생(?)하면 되니 이보다 더 좋을수는 없을 것이다.^^


for loop..for looping... 포루프.... 포루핑(루팡이 아님 --*), 오늘은 반복적인 일을 수행하게 만드는 for문을 공부해 보자. 공식은 아래와 같다.

for (initialization; termination; increment)
{
   statement
}

잘 모르겠으면 아래를 보자.^^

for (초기문; 조건문; 증감문)
{
명령문1;
명령문2;
명령문3;
...
....
.....
}

예제를 보면 이해가 쉬울 것이다. for문에서 세미콜론(;)은 분류를 위해 중간에 두개만 들어간다. for 반복문은 우리가 저번에 배웠던 증감연산자와 뗄래야 뗄수 없는 관계이다. 반복을 시킬수 있는 원동력이 바로 증감연산자이기 때문이다. 그럼 뜸(?) 그만 들일테니 이제 예제를 보자.^^


1부터 3까지 출력하는 예제인데 어떤식으로 반복이 되는지 설명하겠다. for문의 작동원리는 초기값 즉 시작하는 값이 초기문에 있고 그 값을 두번째에 위치한 조건문에 대입해서 조건이 참이면 아래 명령들을 처리하고 거짓이면 for문을 빠져나온다. for문에서 참일때 처리해야하는 명령들은 { } 안에 위치한다. 다시 돌아와서 조건이 참이 나와 명령들을 처리하고 나면 증감문을 실행한다. 증감문이 실행되고 난 후에는 다시 for문으로 돌아와 증감문의 연산대로, 예제의 경우 i값에 1을 더한값이 다시 조건문에 대입되고 위와 같은 과정들을 계속 반복하며 조건문에서 거짓이 나올때까지 for문은 계속 반복된다. 조건문을 만들때는 프로그램의 목적에 따라 반복을 중단해야되는 시점 즉 거짓이 나오는 시점을 반드시 만들어야 한다. 그렇지 않으면 컴퓨터 망가질때까지 for문이 반복(?)될테니까 말이다.ㅎㅎ

본 예제는 i에 0이 들어가면서 for 루프가 시작된다. 그런데 안에 if문이 있는데 0이 아닐때만 i를 출력하라고 한다. 처음의 i값이 0이므로 출력을 하지 않고 다시 for문으로 돌아가 i에 1이 들어가면서 for 룹이 반복된다. 1도 3보다 작거나 같으므로 명령이 처리되며 1은 0이랑 같지 않으므로 이번에는 안에 있는 명령이 실행되면서 1이라는 숫자가 화면에 출력된다. 2도 마찬가지고 3도 마찬가지인데 i에 4가 들어갔을때는 조건문이 거짓이 되므로 for문을 빠져나오며 프로그램이 종료된다. for문에서 초기문의 값은 말 그대로 처음 시작될때 한번만 써먹고 다음엔 써먹을 일이 없다.


위의 예제는 for문에서 초기문과 증감문을 바깥으로 빼고 조건문만 남겨둔 예제이다. 이렇게 초기문이나 증감문을 for문에서 빼내는게 가능하다. 허나 조건문은 꼭 있어야되며 앞과 뒤에 ; 세미콜론은 반드시 있어야 된다. for문의 기본구성을 깨뜨려서는 안되니까 말이다. ^^


위의 두 예제를 보면 하나는 if문에 하나는 for문에 break 명령이 들어가 있다. switch문에서 break 용도에 대해 이미 알아보았는데 이 명령은 switch에서만 쓸수 있는게 아니다. 다른 제어문에서도 쓸수 있다는걸 알려주기 위해 위의 예제를 만들어보았다. 어떤 답이 출력될지 둘다 생각해보고 프로그램을 실행해 보기로 하자. 다 해본걸로 믿고 계속 진행하겠다.

첫번째는 if문에서 break가 걸려있는데 처음의 i값이 0일때는 아예 if문을 들어가지 못하니 break를 만나지 않는다. 반복해서 다시 if문을 만날때는 i값이 1이므로 들어가서 1을 화면에 출력하고 break를 만나므로 그 다음부터는 if문을 실행하지 않는다. 두번째는 처음부터 break를 만나는데 for문에 위치하므로 for문을 더이상 실행하지 않는다. 따라서 for문 이전에 출력을 지시했던 프린트 명령 이외에는 i값을 아무것도 프린트하지 못하고 프로그램이 종료된다. break는 불가피하게 일정 부분에서 알고리즘이 원활하게 수행되지 못할때 임시로 사용하는 개념이 강하다. 여러분이 프로그램을 만들때 예외가 없는 완벽한 알고리즘을 만든다면 break라는 명령은 그리 쓸일이 많지 않을 것이다.

그럼 이번엔 색다른 continue란 키워드에 대해서 공부해 보겠다.


예제를 보면 if문 안에 continue란 명령이 들어가 있다. 이건 무엇을 뜻하는 것인가? continue란 명령을 만날 경우 가장 가까이 있는 for문의 닫는 } 중괄호로 이동한다고 생각하면 된다. 즉 for문에서 증감문이 실행되기 전까지 안에서 행해야될 명령들을 뛰어넘는 것이다. 결과를 보면 아래와 같이 나온다.

0번 루프
0
0체크
1번 루프
2번 루프
3번 루프

처음에는 0이라 continue를 만나지 않으므로 숫자 "0"과 "0체크"라는 표현을 프린트한다. 그러나 두번째부터는 continue를 만나므로 계속해서 for문의 }로 이동을 하므로 다른 명령문들을 처리하지 않는다. continue란 키워드는 잘 쓰이지 않는 편이라 자바를 많이 한 이들도 생소할 것이라 생각된다. 허나 알아두면 써먹을데가 한두번쯤은 나올테니 속는셈치고 공부해보자.^^


위의 예제를 보면 알겠지만 for문은 여러개 쓰는게 가능하다. 우리는 이것을 다중 for문이라 하는데 이런 for loop이 자바에서는 상당히 많이 쓰이므로 어떻게 반복되는지 이번 기회에 확실하게 숙지하기 바란다. C 루프를 보면 continue가 들어있다. 아까 말했던데로 continue를 만나면 가장 가까운 for 루프의 } 닫는 중괄호로 이동해서 증감연산문을 실행하고 다시 그 for 루프의 조건문으로 이동해 값을 비교하면서 프로그램이 계속 진행된다. 여기서는 가장 가까운 for문이 C 루프가 될것이다. 필자가 이번 예제에 온 열정과 정열을 쏟아부었으니 프로그램만 돌려봐도 이해가 절로 될것이다. ^^ 제발~ ㅎㅎ 그럼 결과값은 아래와 같다. 다중 for 루프이므로 무지 길다. --;

========0번 A 루프========
========0번 B 루프========
========0번 C 루프========
a=0, b=0, c=0
All numbers are printed.
========1번 C 루프========
a=0, b=0, c=1
All numbers are printed.
========2번 C 루프========
========1번 B 루프========
========0번 C 루프========
a=0, b=1, c=0
All numbers are printed.
========1번 C 루프========
a=0, b=1, c=1
All numbers are printed.
========2번 C 루프========
========2번 B 루프========
========0번 C 루프========
a=0, b=2, c=0
All numbers are printed.
========1번 C 루프========
a=0, b=2, c=1
All numbers are printed.
========2번 C 루프========
========3번 B 루프========
========0번 C 루프========
a=0, b=3, c=0
All numbers are printed.
========1번 C 루프========
a=0, b=3, c=1
All numbers are printed.
========2번 C 루프========
========1번 A 루프========
========0번 B 루프========
========0번 C 루프========
a=1, b=0, c=0
All numbers are printed.
========1번 C 루프========
a=1, b=0, c=1
All numbers are printed.
========2번 C 루프========
========1번 B 루프========
========0번 C 루프========
a=1, b=1, c=0
All numbers are printed.
========1번 C 루프========
a=1, b=1, c=1
All numbers are printed.
========2번 C 루프========
========2번 B 루프========
========0번 C 루프========
a=1, b=2, c=0
All numbers are printed.
========1번 C 루프========
a=1, b=2, c=1
All numbers are printed.
========2번 C 루프========
========3번 B 루프========
========0번 C 루프========
a=1, b=3, c=0
All numbers are printed.
========1번 C 루프========
a=1, b=3, c=1
All numbers are printed.
========2번 C 루프========
========2번 A 루프========
========0번 B 루프========
========0번 C 루프========
a=2, b=0, c=0
All numbers are printed.
========1번 C 루프========
a=2, b=0, c=1
All numbers are printed.
========2번 C 루프========
========1번 B 루프========
========0번 C 루프========
a=2, b=1, c=0
All numbers are printed.
========1번 C 루프========
a=2, b=1, c=1
All numbers are printed.
========2번 C 루프========
========2번 B 루프========
========0번 C 루프========
a=2, b=2, c=0
All numbers are printed.
========1번 C 루프========
a=2, b=2, c=1
All numbers are printed.
========2번 C 루프========
========3번 B 루프========
========0번 C 루프========
a=2, b=3, c=0
All numbers are printed.
========1번 C 루프========
a=2, b=3, c=1
All numbers are printed.
========2번 C 루프========
========3번 A 루프========
========0번 B 루프========
========0번 C 루프========
a=3, b=0, c=0
All numbers are printed.
========1번 C 루프========
a=3, b=0, c=1
All numbers are printed.
========2번 C 루프========
========1번 B 루프========
========0번 C 루프========
a=3, b=1, c=0
All numbers are printed.
========1번 C 루프========
a=3, b=1, c=1
All numbers are printed.
========2번 C 루프========
========2번 B 루프========
========0번 C 루프========
a=3, b=2, c=0
All numbers are printed.
========1번 C 루프========
a=3, b=2, c=1
All numbers are printed.
========2번 C 루프========
========3번 B 루프========
========0번 C 루프========
a=3, b=3, c=0
All numbers are printed.
========1번 C 루프========
a=3, b=3, c=1
All numbers are printed.
========2번 C 루프========

마지막으로 본 예제에서는 continue를 만났을때 가장 가까운 for문인 C 루프로 이동을 했다. 그러면 그냥 원하는 for문으로 이동할수는 없을까? 물론 있다. continue outer; 라는 명령을 쓰고 이동하고 싶은 for문 앞에 outer: 라고 써주면 그쪽으로 이동한다. 예제를 보고 결과를 비교해보면 어떤 차이가 있는지 알게 될것이다.


========0번 A 루프========
========0번 B 루프========
========0번 C 루프========
a=0, b=0, c=0
All numbers are printed.
========1번 C 루프========
a=0, b=0, c=1
All numbers are printed.
========2번 C 루프========
========1번 A 루프========
========0번 B 루프========
========0번 C 루프========
a=1, b=0, c=0
All numbers are printed.
========1번 C 루프========
a=1, b=0, c=1
All numbers are printed.
========2번 C 루프========
========2번 A 루프========
========0번 B 루프========
========0번 C 루프========
a=2, b=0, c=0
All numbers are printed.
========1번 C 루프========
a=2, b=0, c=1
All numbers are printed.
========2번 C 루프========
========3번 A 루프========
========0번 B 루프========
========0번 C 루프========
a=3, b=0, c=0
All numbers are printed.
========1번 C 루프========
a=3, b=0, c=1
All numbers are printed.
========2번 C 루프========

곁다리로 조금더 공부해 보자면 아래와 같은 for 루프도 있다.

for ( ; ; )
{
..
...
}

이런 식으로 쓰면 infinite loop이라고 하여 무한루프 즉 중지하지 않고 끝없이 반복된다. 그리고 enhanced for 구문이라고 컬렉션과 배열일때 기존의 for 구문에 비해서 유용하게 써먹을수 있는 향상(?)된 기법으로 for loop을 아래와 같이 간단하게 표현할수도 있다.

for (카운트 변수 : 관련 배열)
//중간에 쓴것은 세미콜론이 아니라 그냥 콜론(:)이다.

앞으로는 이런 방식이 대세(?)를 이루게 될것인데 이제 쓰는 방법을 알았으니 아래 예제를 보면서 여러분도 이런 업그레이드된 방법을 쓰는데 익숙해지기 바란다.^^


숫자: 1
숫자: 2
숫자: 3
숫자: 4
숫자: 5


이로서 for문에 대해서 공부해 보았다. 자바에서 for문은 건드리면 툭하고 나올 정도로 많이 쓰이고 특히 다중 for문은 더 자주 쓰여 우리를 매우 피곤하게 할것이니 이번 기회에 개념을 확실하게 정리해놓기 바란다. 그리고 마지막에 본 기존 for문에 비해 보다 파워풀한 성능을 제공하는 enhanced for 구문은 보는 것처럼 내용이 명료하고 쓰기 편하여 여러 프로그램에서 자주 보게될 것이니 어떻게 쓰는지 꼭 기억하기 바란다.^^

댓글 1개:

  1. enhanced for 처음보는데 완전 굿!! 짱짱!! 이런정보를 알아내는 희열..감사합니다!!!!!

    답글삭제