[자바의 정석] 반복문

Jiwon An·2023년 10월 8일
0

Java

목록 보기
8/9

for문

for문은 반복 횟수를 알고 있을 때 적합합니다.

아래의 for문은 블럭{} 내의 문장을 5번 반복합니다.

for(int i=1;i<5;i++) {
	...
}

변수 i에 1을 저장한 다음, 매 반복마다 i의 값을 1씩 증가시킵니다. 그러다가 i의 값이 5를 넘으면 조건식 'i<=5'가 거짓이 되어 반복을 마치게 됩니다.

for문의 구조와 수행순서

for문은 '초기화', '조건식', '증감식', '블럭{}', 모두 4부분으로 이루어져 있으며, 조건식이 참인 동안 블럭{} 내의 문장들을 반복하다 거짓이 되면 반복문을 벗어납니다.

for(초기화;조건식;증감식) {
	// 조건식이 참일 때 수행될 문장들을 적는다.
}

제일 먼저 초기화가 수행되고, 그 이후부터는 조건식이 참인 동안 조건식 -> 수행될 문장 -> 증감식 의 순서로 계속 반복됩니다. 그러다가 조건식이 거짓이 되면, for문 전체를 빠져나가게 됩니다.

초기화

반복문에 사용될 변수를 초기화하는 부분이며 처음에 한번만 수행됩니다. 보통 변수 하나로 for문을 제어하지만, 둘 이상의 변수가 필요할 때는 아래와 같이 콤마','를 구분자로 변수를 초기화하면 됩니다. 단, 두 변수의 타입은 같아야 합니다.

for(int i=1;i<=10;i++) { ... } // 변수 i의 값을 1로 초기화
for(int i=1,j=0;i<=10;i++) { ... } // int타입의 변수 i, j를 선언하고 초기화

조건식

조건식의 값이 참(true)이면 반복을 계속하고, 거짓(false)이면 반복을 중단하고 for문을 벗어납니다.

for(int i=1;i<=10;i++) { ... } // 'i<=10'가 참인 동안 블럭{}안의 문장들을 반복

조건식을 잘못 작성하면 블럭{} 내의 문장이 한 번도 수행되지 않거나 영원히 반복되는 무한반복에 빠지기 쉬우므로 주의해야 합니다.

증감식

반복문을 제어하는 변수의 값을 증가 또는 감소시키는 식입니다. 매 반복마다 변수의 값이 증감식에 의해서 점진적으로 변하다가 결국 조건식이 거짓이 되어 for문을 벗어나게 됩니다.

for(int i=1;i<=10;i++) { ... } // 1부터 10까지 1씩 증가
for(int i=10;i>=1;i--) { ... } // 10부터 1까지 1씩 감소
for(int i=10;i>=1;i+=2) { ... } // 1부터 10까지 2씩 증가

증감식도 쉼표','를 이용해서 두 문장 이상을 하나로 연결해서 쓸 수 있습니다.

for(int i=1;i<=10;i++, j--) { ... } // i는 1부터 10까지 1씩 증가
									// j는 10부터 1까지 1씩 감소

초기화, 조건식, 증감식 이 세 가지 요소는 필요하지 않으면 생략할 수 있으며, 심지어 모두 생략하는 것도 가능합니다.

for(;;) { ... } // 초기화, 조건식, 증감식 모두 생략. 조건식은 참이 됨

변수를 줄이자

for문을 작성할 땐 for문에 사용되는 변수의 수가 적은 것이 더 효율적이고 간단하므로 변수들의 관계를 잘 파악하여 불필요한 변수의 사용을 줄이는 것이 좋습니다.

before

for(int i=1;j=10;i<=10;i++,j--) {
	System.out.println("%d \t %d%n", i, j);
}

after

for(int i=1;i<=10;i++) {
	System.out.println("%d \t %d%n", i, 11-i);
}

중첩 for문

for문 안에 또 다른 for문을 포함시키는 것도 가능합니다. 그리고 중첩의 횟수는 거의 제한이 없습니다.

for(int i=1;i<5;i++) {
	for (int j=1;j<5;j++) {
    	... 
    }
}

안쪽 for문의 내부에 문장이 하나면 괄호를 생략할 수 있습니다.

for(int i=1;i<5;i++) {
	for (int j=1;j<5;j++)
    	System.out.println('*');
}

바깥쪽 for문에게는 안 쪽 for문 전체가 하나의 문장이므로 바깥쪽 for문의 괄호{}도 생략이 가능합니다.

for(int i=1;i<5;i++) 
	for (int j=1;j<5;j++)
    	System.out.println('*');

되도록이면 괄호{}를 사용하는 것이 좋지만 너무 많아도 복잡하므로 경우에 따라서는 간략하게 생략해도 좋습니다.

향상된 for문

JDK1.5부터 배열과 컬렉션에 저장된 요소에 접근할 때 아래의 방법으로 처리할 수 있습니다.

for( 타입 변수명 : 배열 또는 컬렉션 ) {
	// 반복할 문장
}

타입은 배열 또는 컬렉션의 요소의 타입이어야 합니다. 배열 또는 컬렉션에 저장된 값이 매 반복마다 하나씩 순서대로 읽혀서 변수에 저장됩니다. 그리고 반복문의 괄호{}내에서는 이 변수를 사용해서 코드를 작성합니다.

int[] arr = {1, 2, 3, 4, 5};

// ** 배열의 모든 요소 출력하기 ** 

// 일반적인 for문
for(int i=0; i<arr.length; i++) {
	...
}

// 향상된 for문
for(int tmp : arr) {
	...
}

향상된 for문이 더 간결하지만 향상된 for문은 일반적인 for문과 달리 배열이나 컬렉션에 저장된 요소들을 읽어오는 용도로만 사용할 수 있다는 제약이 있습니다.

while문

if문과 달리 while문은 조건식이 '참(true)인 동안', 즉 조건식이 거짓이 될 때까지 블럭{} 내의 문장을 반복합니다.

while (조건식) {
	// 조건식의 연산결과가 참(true)인 동안, 반복될 문장들을 적는다.
}

while문은 먼저 조건식을 평가해서 조건식이 거짓이면 while문을 벗어나고, 참이면 블럭{} 내의 문장을 수행하고 다시 조건식으로 돌아갑니다. 조건식이 거짓이 될 때까지 이 과정이 계속 반복됩니다.

for문과 while문 비교

for문은 초기화, 조건식, 증감식을 한 곳에 모아 놓은 것일 뿐, while문과 다르지 않습니다. 그래서 for문과 while문은 항상 서로 변환이 가능합니다. 만일 초기화나 증감식이 필요하지 않은 경우라면, while문이 더 적합할 것입니다.

  1. for문

    // 초기화, 조건식, 증감식
    for(int i=1;i<=10;i++) { 
    	...
    }
  2. while문

    	int i=1; // 초기화
        
        while(i<=10) { // 조건식
        	...
            i++ // 증감식
        }

while문의 조건식은 생략불가

한 가지 주의할 점은 for문과 달리 while문의 조건식은 생략할 수 없습니다.

while () { // 에러. 조건식이 없음
	...
}

그래서 while문의 조건식이 항상 참이 되도록 하려면 반드시 true를 넣어야 합니다. 다음의 두 반복문은 블럭{} 내의 문장을 무한 반복합니다.

for (;;) { // 조건식이 항상 참			while(true) { // 조건식이 항상 참
	...									...
}									}

무한 반복문은 반드시 블럭{}안에 조건문을 넣어서 특정 조건을 만족하면 무한 반복문을 벗어나도록 해야 합니다.

do-while문

do-while문은 while문의 변형으로 기본적인 구조는 while문과 같으나 조건식과 블럭{}의 순서를 바꿔놓은 것입니다. 그래서 while문과 반대로 블럭{}을 먼저 수행한 후에 조건식을 평가합니다. while문은 조건식의 결과에 따라 블럭{}이 한 번도 수행되지 않을 수 있지만, do-while문은 최소한 한번은 수행될 것을 보장합니다.

그리 많이 쓰이지는 않지만, 반복적으로 사용자의 입력을 받아서 처리할 때 유용합니다.

do {
	// 조건식의 연산결과가 참일 때 수행될 문장들을 적는다.
} while (조건식);

break문

break문은 자신이 포함된 가장 가까운 반복문을 벗어납니다. 주로 if문과 함께 사용되어 특정 조건을 만족하면 반복문을 벗어나도록 합니다.

while(true) {
	if (sum > 100)
    	break;
}

continue

continue문은 반복문 내에서만 사용될 수 있으며, 반복이 진행되는 도중에 continue문을 만나면 반복문의 끝으로 이동하여 다음 반복으로 넘어갑니다. for문의 경우 증감식으로 이동하며, while문과 do-while문의 경우 조건식으로 이동합니다.

주로 if문과 함께 사용되어 특정 조건을 만족하는 경우에 continue문 이후의 문장들을 수행하지 않고 다음 반복으로 넘어가서 계속 진행하도록 합니다.
전체 반복 중에 특정조건을 만족하는 경우를 제외하고자 할 때 유용합니다.

for(int i=0;i<=10;i++) {
	if (i%3 == 0) 
    	continue; // 조건식이 참이 되어 continue문이 수행되면 블럭의 끝으로 이동
		          // break문과 달리 반복문을 벗어나지 않음
}

이름 붙은 반복문

break문은 근접한 단 하나의 반복문만 벗어날 수 있기 때문에, 여러 개의 반복문이 중첩된 경우에는 break문으로 중첩 반복문을 완전히 벗어날 수 없습니다. 이때는 중첩 반복문 앞에 이름을 붙이고 break문과 continue문에 이름을 지정해 줌으로써 하나 이상의 반복문을 벗어나거나 반복을 건너뛸 수 있습니다.

public static void main(String[] args) {
	// for문에 Loop1이라는 이름을 붙였다.
    Loop1 : for(int i=2;i<=9;i++) {
    	for (int j=1;j<=9;j++) {
        	if (j==5) 
            	break Loop1; // Loop1 for문을 나간다.
                break; // 가장 가까운 for문만 나간다.
                continue Loop1; // Loop1의 마지막으로 이동한다.
                continue; // 가장 가까운 for문의 마지막으로 이동한다. 
        }
    }
}

continue Loop1;과 같은 문장을 쓸 일은 거의 없을 테니 무시해도 좋다.

profile
🚀 백엔드 2년차 개발자입니다 🚀 성장의 즐거움으로 아자자자!🤣

0개의 댓글