자바 while문
목차
자바 while문도 for문과 같은 반복문입니다. 루프(loop)를 한다는 동작에 있어서 for문과 차이는 없습니다. 하지만 가독성은 차이가 있는데요.
for문이 정해진 횟수를 반복하는데 주로 사용한다면 while문은 ‘조건식이 참일 동안 반복 수행’ 하는데 사용합니다.
for문은 헤드(head) 부분에 많은 정보가 들어있지만 while문은 첫줄에 조건식밖에 나오지 않습니다.
while문 기초
while(조건식){ 코드블록; }
어떠한 조건에 도달할 때까지 반복한다는 의미입니다.
for문과 while문의 차이는 사람의 문장으로 만들었을 때 잘 드러납니다.
‘for문에서는 1부터 100까지의 수를 더하라’ 는 문장은 ‘while문에서는 100이 될때까지 더하라’는 말로 바꿀 수 있습니다.
다음의 while 문을 알아보겠습니다.
public static void main(String[] args) { int count = 1; int sum = 0; while(count <= 100){ sum += count++; } System.out.println("count = " + count); System.out.println("sum = " + sum); }
count = 101 sum = 5050
for문과 다른 부분이 눈에 들어옵니다. while 문의 조건식이 보여주는 것은 count <= 100 즉 100보다 작으면 실행하라는 말입니다.
대신 for문에 있었던 조건식에 대한 카운터(인덱스)의 증감이나 초기화 같은 것은 없습니다. while문은 조건식 이외는 프로그래머가 알아서 작성해야 합니다.
이 차이가 사소할 수도 있지만 바라보는 관점에 따라 큰 차이가 될 수 있습니다. 가장 보편적인 방식은 while 무한루프입니다.
다음의 코드는 while문의 성질을 잘 나타내고 있습니다.
public static void main(String[] args) { boolean running = true; int count = 0; while(running){ System.out.println("while loop, " + count++); if(count == 5) running = false; } System.out.println("while loop ended, count = " + count); }
while loop, 0 while loop, 1 while loop, 2 while loop, 3 while loop, 4 while loop ended, count = 5
while(running)에서 running 은 boolean 타입입니다. true에서 블록을 실행 false에서 이탈합니다. while(true)는 무한루프(무한히 반복한다)이므로 if문으로 조건을 false로 변경합니다.
running = false는 while문을 종료시키는 스위치입니다. 대신 break 문을 사용할 수도 있습니다. 어느쪽도 같은 결과를 가져오지만 while문을 보는 관점에서 차이가 납니다.
이렇게 자바에서는 같은 동작에 대하여 여러가지 방법 즉 알고리즘을 사용할 수 있는데요. 지금은 단지 문법적인 해석이기만 실제 프로그램을 설계 시 에도 고려할 내용입니다.
while문 구구단(중첩)
public static void main(String[] args) { int i, j = 0; i = 2; j = 1; while(i <= 9){ j = 1; while(j <= 9){ System.out.printf("%dx%d=%2d | ", i, j, i*j); j++; } System.out.printf("\n"); i++; } System.out.println("i = " + i); System.out.println("j = " + j); }
2x1= 2 | 2x2= 4 | 2x3= 6 | 2x4= 8 | 2x5=10 | 2x6=12 | 2x7=14 | 2x8=16 | 2x9=18 | 3x1= 3 | 3x2= 6 | 3x3= 9 | 3x4=12 | 3x5=15 | 3x6=18 | 3x7=21 | 3x8=24 | 3x9=27 | 4x1= 4 | 4x2= 8 | 4x3=12 | 4x4=16 | 4x5=20 | 4x6=24 | 4x7=28 | 4x8=32 | 4x9=36 | 5x1= 5 | 5x2=10 | 5x3=15 | 5x4=20 | 5x5=25 | 5x6=30 | 5x7=35 | 5x8=40 | 5x9=45 | 6x1= 6 | 6x2=12 | 6x3=18 | 6x4=24 | 6x5=30 | 6x6=36 | 6x7=42 | 6x8=48 | 6x9=54 | 7x1= 7 | 7x2=14 | 7x3=21 | 7x4=28 | 7x5=35 | 7x6=42 | 7x7=49 | 7x8=56 | 7x9=63 | 8x1= 8 | 8x2=16 | 8x3=24 | 8x4=32 | 8x5=40 | 8x6=48 | 8x7=56 | 8x8=64 | 8x9=72 | 9x1= 9 | 9x2=18 | 9x3=27 | 9x4=36 | 9x5=45 | 9x6=54 | 9x7=63 | 9x8=72 | 9x9=81 | i = 10 j = 10
for문에서 구구단은 2차원 배열과 같다고 설명했습니다.
while문으로 구구단을 작성하다 보면 for문과 큰 차이를 느낄 수 있습니다.
while문을 작성하는 동안 for문에서는 신경쓰지 않았던 index i, j 의 초기화까지 별도로 해야합니다.
초기화를 직접한다는 것은 프로그래머가 책임질 부분이 많다는 것을 의미합니다. 프로그래밍 문법에서 책임을 많이 지면 그 만큼 제어 권한이 많아지고, 책임질 일이 적어지면 권한이 줄어듭니다.
컴퓨터구조를 학습할 때 기계의 가상화, 추상화 단계에 대한 이야기도 관련이 있습니다만, 여기서 다루기는 편하지 않기에 상세 설명은 하지 않겠습니다.
입문자들은 while문과 for문의 차이에 대하여 인식할 수만 있어도 큰 의미가 있습니다. 보통 처음 시작할 때는 while인지 for인지 그게 그거 같아서 자각을 잘 못하기 때문입니다.
while문 삼각형 그리기
for문 처럼 while로도 삼각형을 그려보겠습니다.
public static void main(String[] args) { int i = 1, j = 1; int size = 7; while(i <= size){ j = 1; while(j <= i){ System.out.printf("*"); j++; } System.out.printf("\n"); i++; } System.out.println("i = " + i); System.out.println("j = " + j); }
* ** *** **** ***** ****** ******* i = 8 j = 8
직접 초기화를 하다보니 코드가 더 복잡해 보이지만 결과는 같습니다.
while문 도형의 몇가지 응용
while문으로 도형을 그리면서 응용을 해봅니다.
public static void main(String[] args) { int i = 1, j = 1; int size = 7; while(i <= size){ j = 1; while(j <= i){ System.out.printf("*"); j++; } j = 1; System.out.print("\\"); while(j <= i){ System.out.printf("*"); j++; } j = 1; System.out.print("\\"); while(j <= i){ System.out.printf("*"); j++; } System.out.printf("\n"); i++; } }
*\*\* **\**\** ***\***\*** ****\****\**** *****\*****\***** ******\******\****** *******\*******\*******
도형 그리기를 통해 직관적인 감각을 기를 수 있습니다. 저 별 기호는 숫자가 될수도 있는 제어 흐름입니다.
public static void main(String[] args) { int i = 1, j = 1; int size = 7; while(i <= size){ j = i; while(j <= size){ System.out.printf("*"); j++; } j = 1; System.out.print("/"); while(j <= i){ System.out.printf("*"); j++; } System.out.printf("\n"); i++; } }
*******/* ******/** *****/*** ****/**** ***/***** **/****** */*******
삼각형도 사각형도 만들수 있고 여기서 다루지는 않지만 수학식을 응용하여 원을 그리거나 차원을 늘려서 3차원 그래픽도 표현할 수 있습니다.
대부분 교재는 거기까지 가지도 못하는데요. 그래서 나중에 사람들이 알고리즘이 중요하다고 이야기 하는 것 입니다. 문법적 교육과 알고리즘 교육이 분리가 되서 그렇습니다. 안 그러면 교육시간이 너무 많아지니까요.
하지만 웹사이트 학습에는 그런 제한이 없고 이것은 장점입니다. 마찬가지로 실전에 서도 교육시간은 무의미합니다. 교육을 많이 받았는가와 상관없이 실제 사례에 제대로 적용 가능한지 여부가 중요합니다.
요약
자바 while문을 알아봤습니다.
일반 애플리케이션에서 가장 흔한 while문의 예를 들으면 프로그램의 GUI 부분입니다. 우리가 사용하는 모든 프로그램은 명령프롬프트이건 GUI 이건 무한루프 로직으로 돌고 있습니다. 때문에 우리가 키보드나 마우스를 클릭했을 때 화면에 즉각 반영되는 것 입니다.
앱개발을 위해 프레임워크를 사용할 때 보면 무한루프 로직이 프레임워크 안에 이미 구현되있거나 혹은 프로그래머가 직접 무한루프를 구현해야 하는 경우도 있습니다.
while에서 무한루프 개념을 잘 이해한다면 어떤 식으로 프레임워크를 사용할지 감을 잡기 쉽습니다.
네트워크 프로그래밍은 좀 다른데요. 하지만 아이디어가 무엇인지 알아내는데 도움이 됩니다. 이쪽 컴퓨터(클라이언트)와 저쪽 컴퓨터(서버)간 무한정 통신을 해야하는데 스피드가 다르기 때문에 어떤 식으로 연결을 구상할 것인가 설계하는 것 입니다.
따지고 보면 다 같은 말이기도 틀린 말이기도 합니다. 여기서 이야기하는 것은 본질에 대한 것 입니다.
이번 포스팅은 많은 내용을 설명하려고 했습니다만, 자바는 C와 다르게 개념적으로 파고들 필요도 있습니다. 자바의 코스는 보통 변수와 자료형, 제어문 다음에 함수를 배우지 않고 바로 객체지향으로 들어가기 때문에 개념부터 파고들어 갑니다.
C언어 계열에서는 제어문 다음에 배열로 자료구조를 설명한 후 함수에서 메모리와 포인터를 학습합니다.
C언어는 중간(middle)에서 시작해서 저수준(low level)으로 내려가는 학습방식이라면 자바도 시작은 중간(middle)인 것은 같지만 고수준(high level)인 객체 모형으로 올라가는 구조로 되있습니다.
이제 여기 제어문 부분이 갈림길이죠. 어느쪽이 더 쉽다 그런 문제는 아니지만 객체지향이 절대 만만하지 않습니다. 나중에 가면 C언어보다 더 어렵고 난해하기 때문에 여기서 각오를 단단하게 먹어야 합니다.
그러고 보니 C언어는 포인터와 메모리에서 자주 관두고 자바는 객체지향에서 헤메게 되는 것 같습니다. 일단 제어흐름 다음으로 넘어가면 이제 본격적으로 시작입니다.
외부참조문서
자바 튜토리얼 (4-3) 반복문 (자바 while문, 자바 do while문)