반복문은 어떤 작업(코드)이 반복적으로 실행되도록 할 때 사용되며, 반복문의 종류로는 for문, while문, do-while문이 있습니다. for문과 while문은 서로 변환이 가능하므로 어느 쪽을 선택해도 상관이 없지만 for문은 반복횟수를 알고 있을 때 주로 사용하고, while문은 조건에 따라 반복할 때 주로 사용합니다. while문과 do-while문은 조건을 먼저 검사하느냐 나중에 검사하느냐일 뿐 동작 방식은 동일합니다.
for문
프로그램을 작성하다 보면 똑같은 실행문을 반복적으로 실행해야 하는 경우가 많이 발생합니다. 이런 경우 사용하는 것이 반복문인데 for문은 주로 반복문의 반복 횟수를 아는 경우 사용합니다. 다음 예제를 한번 살펴보겠습니다.
int sum = 0;
sum = sum + 1;
sum = sum + 2;
sum = sum + 3;
sum = sum + 4;
sum = sum + 5;
System.out.println("1-5의 합: " + sum);
이와 같은 경우 반복문을 사용한다면 좀 더 간단하게 사용할 수 있습니다. 위의 예제는 단순히 5까지의 합이지만 100까지의 합이라면 어떨까요? 코드를 100번을 작성할 수는 없을 것입니다. 이렇게 반복되는 경우 반복문을 사용하는데 이처럼 특정 숫자까지 반복을 한다면 for문이 가장 어울릴 것 입니다. 1부터 100까지 더하는 것을 for문을 사용해서 표현해보도록 하겠습니다.
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum = sum + i;
}
System.out.println("1-100의 합: " + sum);
위의 예제를 보면 for문의 안의 처음에 초기화식인 int i = 1;이 주어집니다. 이는 정수타입의 i를 생성하고 1을 지정하라는 얘기입니다. 그다음은 조건식인 i <= 100;이 주어집니다. 이는 i가 100이하인 경우 참이 되므로 계속 반복문을 실행하도록 합니다. 마지막으로 증감식인 i++이 존재합니다. 이는 반복문을 실행하고 나서 i값을 1씩 증가시키라는 뜻입니다. 그래서 i는 1부터 하나씩 증가하여 100까지 가게되고 for문은 100번 수행하게 됩니다. 반복문은 sum = sum + i;는 처음에는 i가 1이므로 sum = sum + 1;이되고 그다음에는 i가 1이 증가되어 2가 되므로 sum = sum + 2;가 됩니다. 이렇게 해서 sum = sum + 100까지 실행하게 됩니다. 전에 연산식에서 배웠듯이 sum = sum + i;는 sum += i;로 대치될 수 있습니다.
위의 실행코드를 보면 좀 전에 설명했던 예제와 비슷한 면이 많이 있습니다. 실제로 결과를 똑같습니다. 하지만 여기서 차이점을 살펴보아야합니다. 첫번째로 라인 7에 i를 선언했습니다. 여기서는 i를 for문 위에 선언했으므로 for문이 종료된 후에도 i가 존재합니다. 이는 변수의 범위를 알아야하는데 변수는 선언된 중괄호 안에서만 효력이 있으며 벗어나는 순간 더 이상 존재하지 않는 변수가 됩니다. 그래서 라인 12에서 i를 사용하기위해서 for문 위에 선언한 것입니다. 라인 12에서 i값에 따라 값이 출력될 수 있도록 했습니다. i가 100까지 true이기 때문에 for문을 벗어날 때는 i가 101이 됩니다. 그래서 출력문에서 i-1을 해서 100이 되도록 한 것입니다. 이와같이 100을 직접 입력하지 않고 i-1을 사용한 것은 좀 더 바람직한 코드라고 볼 수 있습니다. for문에서 100까지의 합을 구하는 것이라서 숫자100을 썼지만 실제 프로그램에서는 이렇듯 100이라는 상수를 쓰기보다는 입력된 값이나 DB에서 얻어온 값을 사용하는 경우가 대부분입니다. 그래서 출력문에서처럼 i-1을 사용해서 어떤 값이 들어오더라도 실행될 수 있도록 해야되는 것입니다.
중첩 for문
for문은 또 다른 for문을 내포할 수 있는데, 잉것을 중첩 for문(nested for loop)이라고 합니다. 이 경우 바깥쪽 for문이 한 번 실행할 때마다 중첩된 for문은 지정된 횟수만큼 반복해서 돌다가 다시 바깥쪽 for문으로 돌아갑니다. 예제를 보시면 좀 더 이애가 빠르실 겁니다.
위의 예제는 구구단을 출력하는 프로그램입니다. 길어서 캡쳐가 다 되지는 않았지만 2단부터 9단까지 출력되었습니다. 바깥쪽 for문은 각단을 나타낸 것이고 안쪽의 for문은 각 단안의 1부터 9까지의 곱하기를 나타낸 것입니다. 2개 이상의 중첩된 for문도 가능하기는 하지만 여러개를 중첩시키면 로직이 복잡해지고 다른 사람들이 이해하기 어렵기때문에 사용을 자제하는 것이 좋습니다. 요즘 프로그램에서 가장 중요하다고 생각하는 것은 가독성입니다. 다른 사람이 봐서 이해하기 쉬워야 한다는 뜻이지요.
while문
for문이 정해진 횟수만큼 반복한다면, while문은 조건식이 true일 경우에 계속해서 박복합니다. 조건식에는 비교 또는 논리 연산식이 주로 오는데, 조건식이 false가 되면 반복을 멈추고 while문을 죵료합니다. 아까 for문으로 작성했던 1부터 100까지의 합을 구하는 프로그램을 while문으로 작성해보도록 하겠습니다.
위에서 작성한 for문과 똑같은 결과를 나타내는 프로그램입니다. 이 경우는 for문이 좀 더 이해하기 쉽고 간결해 보일겁니다. 이처럼 반복횟수가 정해진 경우는 for문으로 작성하는게 좀 더 보기가 좋습니다. 하지만 반복횟수가 정해지지 않고 조건식에 의해서 반복이 결정되는 경우에는 while이 더 적합합니다.
do-while문
do-while문은 조건식에 의해 반복 실행한다는 점에서는 while문과 동일합니다. while문은 시작할 때 조건식을 검사하여 블록 내부를 실행할지 결정하지만, do-while문은 처음에는 무조건 실행하고 나서 나중에 조건식을 검사합니다. 일반적으로 반복문 중에서 사용빈도가 가장 낮습니다.
break문
break문은 반복문인 for문, while문, do-while문의 실행을 중지할 때 사용됩니다. 이는 굉장히 중요한 개념이고 반복문을 할 때 굉장히 많이 쓰입니다. 다음 예제를 통해 break 사용법을 알아 봅시다.
위의 예제는 주사위를 굴려서 6이 나올때까지 반복하는 프로그램입니다. 이전에 소개했던 Math.random() 메소드를 사용했습니다. 이것은 0부터 1보다 작은 수를 리턴하는 메소드입니다. 그래서 0 <= (Math.random() * 6) < 6 입니다. 그래서 여기에 1을 더하고 정수형으로 바꾸면 1부터 6까지 사이의 값을 무작위로 나타내줍니다. 그래서 6이 나올때까지 계속해서 반복문을 반복하는 프로그램입니다. 그런데 여기서 while문 조건식에 true을 사용했습니다. 이는 항상 참이므로 while문장은 무한루프입니다. 그래서 중간에 if를 통해 조건을 검사하고 num이 6이 되면 while문을 종료할 수 있도록 break문을 사용해준 것입니다. 여기서 break문을 사용하지 않았다면 프로그램은 종료하지 않고 계속 수행하게 되고 강제로 프로그램을 종료할 수 밖에 없습니다. 하지만 위의 프로그램은 do-while문을 사용한다면 break문을 사용하지 않고도 작성할 수 있습니다.
위의 프로그램과 같은 프로그램인데 do-while문을 사용해서 작성한 것입니다. 이처럼 프로그램은 여러가지 방식으로 작성할 수 있고 어떤 것이 정답이라고 말할 수는 없지만 좀 더 효율적이거나 보기 쉬운 것은 존재합니다. 여기서는 do-while문을 사용하는 것이 가장 효율적이게 보이기는 하지만 사람들이 while문을 더 많이 사용하고 위의 while문장이 좀 더 이해하기 쉬울 수도 있으므로 어느 것이 낫다라고 정확히 말할 수는 없지만 두가지 모두 사용할 수 있도록 좀 더 유용할 것 같습니다.
continue문
continue문은 반복문 블록내에서 사용하는데 continue문을 만나면 continue이후의 문장을 실행하지 않고 반복문의 조건식으로 올라가게 됩니다. 즉 반복문의 마지막을 ㅁ나나고 다음을 실행하는 것과 같은 효과를 내는 것입니다. 다음 예제를 통해 살펴보도록 하겠습니다.
위의 예제는 1부터 10사이의 짝수를 출력하는 프로그램입니다. for문은 1부터 10까지 10번을 실행하지만 if문장에 의해서 짝수가 아닌 경우는 continue문을 만나게 되고 그러면 다시 for문으로 돌아가서 i를 1증가시킵니다. 위의 예도 사실 continue를 설명하기 위해 만든 프로그램입니다. 실제 프로그램에서는 이렇게 작성하지 않을 것입니다. 그냥 간단히 for(int i = 2; i <= 10; i+=2) 이렇게 작성하고 그냥 출력을 하면 되니까요. 여러번 얘기했지만 프로그램은 프로그래머의 역량과 알고리즘에 따라 작성을 하게 됩니다. 그래서 정답은 없다라고 얘기하지만 제 생각은 조금 다릅니다. 정답은 없겠지만 정답에 비슷한 답은 존재하고 전혀 비효율적이고 잘못된 프로그램도 존재합니다. 제가 나중에 알고리즘에 대해 얘기하면서 몇가지 프로그램에 대한 예를 들 것입니다. 예전에 솟수를 출력하는 프로그램을 작성한 적이 있습니다. 그냥 알고리즘 공부때문에 작성한 프로그램입니다. 단순히 솟수 하나만 출력한다면 어떻게 프로그램을 작성하여도 큰 차이는 없을 것입니다. 그렇지만 어떤 숫자 n을 입력받고 2부터 그 숫자까지의 모든 솟수를 구하는 프로그램이라면 얘기가 좀 다릅니다. n이 엄청 큰 숫자인 경우는 요즘 컴퓨터라 할지라도 엄청난 차이를 보입니다. 제가 작성한 가장 비효율적인 프로그램과 가장 효율적인 프로그램이 보인 속도의 차이는 엄청났습니다. 좀 더 효율적이거나 보기 쉽게 프로그램을 작성하도록 노력한다면 더 좋은 결과를 낼 수 있을 것입니다. 그래서 단순히 언어만 배울 것이 아니라 프로그램을 어떻게 작성할 것인가를 고민하는 알고리즘을 배우는 것을 추천드립니다.
'프로그래밍 > Java 프로그래밍' 카테고리의 다른 글
자바의 배열 (0) | 2020.07.03 |
---|---|
자바 참조 타입과 참조변수 (0) | 2020.07.02 |
자바 조건문 (0) | 2020.06.29 |
자바연산자와 연산식4 (0) | 2020.06.29 |
자바 연산자와 연산식3 (0) | 2020.06.28 |