📗반복문

여러분은 형제나 자매가 있나요? 저는 남동생이 있습니다.

제가 프로그래밍에 입문하게 된 계기 중 하나도 바로 제 동생이 컴퓨터 공학과 학생이었기 때문인데요. 옛날에는 정말 코찔찔이였는데 지금은 미국 실리콘밸리에서 아이 둘을 키우며 구글에서 데이터 사이언티스트로 커리어를 쌓아나가고 있습니다.

하지만 얻는게 있으면 잃는것도 있듯이, 머리숱은 상당히 많이 잃었습니다.

저는 어렸을때, 제 동생에게 명령을 많이 내렸습니다. 그 중 상당수는 반복적인 작업이었죠.

"물 한컵 떠와."

(5분 후)

"물 한컵 떠와."

(5분 후)

"물 한컵 떠와."

...

(10번째) "물 한컵 떠와."

이런 반복적인 논리를 프로그래밍에서 구현해야 하는 경우, 우리는 반복문을 이용해서 논리 전개를 구현할 수 있습니다.

코드부터 한번 볼까요?

for (let i = 0; i < 10; i++) {
  console.log("물 한컵 떠와.");
}

위 구문을 실행하면 아래와 같이 10개의 문자열이 반복적으로 출력되는 것을 확인할 수 있습니다.

작동방식을 파악하기 위해서는 코드를 변경해가며 어떻게 동작하는지 살펴보는 시간을 갖는게 좋을것 같습니다.

우선 다음과 같이 한번 바꿔보겠습니다. let i = 0; 이라는 구절을 let i = 5; 로 변경해볼까요?

for (let i = 5; i < 10; i++) {
  console.log(`${i}) 물 한컵 떠와.`);
}

출력문을 살펴보면, i 값이 5부터 9까지 순차적으로 진행된 것을 확인할 수 있네요.

이번에는 비교 연산자를 < 에서 <= 로 변경해볼까요?

for (let i = 5; i <= 10; i++) {
  console.log(`${i}) 물 한컵 떠와.`);
}

저는 호기심이 많아서 또 변경해보겠습니다.

for (let i = 5; i === 10; i++) {
  console.log(`${i}) 물 한컵 떠와.`);
}

이렇게 바꾸니 아래처럼 아무것도 출력되지 않는군요.. 🧐 다시 이전처럼 되돌아가야겠습니다.

대신 뒷 부분을 한번 변경해보겠습니다.

for (let i = 5; i <= 10; i = i + 5) {
  console.log(`${i}) 물 한컵 떠와.`);
}

i++ 구문 대신, i 를 5만큼 증가시키는 구문을 넣었습니다. 그랬더니 아래처럼 출력문이 바뀌었네요. 😑

대략 느낌 상 정리해보자면, "어디서부터 어디까지 어떤 구절을 얼마나 자주 반복해줘!"라는 문법적 기능을 하는 것 같다는 인상이 드셨나요? 그렇다면 제 의도가 성공한것 같네요. 😌

정확한 문법적 기능은 지금 이야기한 것과는 조금 다르기 때문에, 잠시 후에 문법적 기능에 대해 깊이있게 살펴보겠습니다.

방금 보신 것처럼 반복문은 숫자 변수를 기준으로 하여 반복 작업을 수행하기 때문에 다음과 같이 활용해볼 수도 있습니다.

const str = "hello";

// 한 글자씩 출력
for (let i = 0; i < 5; i++) {
  console.log(`${i + 1}번째 글자는 "${str[i]}"입니다.`);
}

그런데, i < 5 구문에서 우리는 5 대신 문자열의 길이(.length) 속성을 활용해 볼 수 있습니다.

const str = "hello";

// 한 글자씩 출력
for (let i = 0; i < str.length; i++) {
  console.log(`${i + 1}번째 글자는 "${str[i]}"입니다.`);
}

다음과 같이 출력되는 것을 확인할 수 있죠? 😎 str 변수의 값을 "hello" 문자열 대신 다른 어떤 텍스트로 변경해도 우리의 로직은 대응이 가능합니다. 후후..

만약에 다음과 같은 문자열이 주어져있다고 생각해보세요.

const str = "살삼치삼살삼";

우리는 위와 같이 생긴 문자열에서 0, 2, 4번째 인덱스에 위치한 문자열들을 뽑아서 "살치살" 이라는 문자열을 도출해내야 합니다. 어떻게 할 수 있을까요?

반복문을 사용하는 방법도 있기는 합니다만, 우선 반복문을 사용할 생각을 하기보다는 그냥 단순히 문제를 해결하는 코드를 작성해보겠습니다.

단순히 접근한다면, 저는 아래와 같이 코드를 작성할것 같습니다.

const str = "살삼치삼살삼";
const result = str[0] + str[2] + str[4];

console.log(result);

이 코드를 실행시켜보면 우리가 원하는 결과가 잘 출력되고 있습니다.

이제 다양한 방법으로 문제해결을 시도해보는 것이 좋으니, 다른 방법도 한번 시도해보겠습니다.

우리 코드를 보니, 제 눈에는 반복되는 구절이 보이네요.

반복되는 구절은 숫자 인덱스가 사용되고 있고, 인덱스가 증가하는 일정한 패턴이 존재해보입니다. 그렇기에 반복문으로서 처리가 가능할것 같네요. 🥸

시각적으로 반복되는 구문이라고 해서 모두 반복문으로 개선할 수 있는건 아닐 수 있습니다.

현재 반복되는 구절은 인덱스가 2부터 시작해서 4까지 반복되고, 2만큼 1번 증가했습니다. 그러므로 반복문의 구조는 기본적으로 아래와 같습니다.

for (let i = 2; i <= 4; i += 2) {
  // something..
}

그리고 이제 우리는 각 인덱스에 위치한 문자열을 result 문자열에 누적시키는 논리를 추가해야 합니다. result 문자열은 재할당이 필요해졌으므로, let 으로 변경했습니다.

const str = "살삼치삼살삼";
let result = str[0];

for (let i = 2; i <= 4; i += 2) {
  result = result + str[i];
}

console.log(result);

혹은 아래와 같이 해도 동일한 내용이겠죠?

const str = "살삼치삼살삼";
let result = "";

for (let i = 0; i <= 4; i += 2) {
  result += str[i];
}

console.log(result);

구조 뜯어보기

반복문을 한번 자세히 살펴보도록 하겠습니다.

반복문에는 세미콜론과 중괄호를 기준으로 크게 4가지 파트가 있습니다.

1️⃣ 번 - Initialization / 초기화 구절

반복문의 실행이 시작되는 시점에 가장 먼저 실행되는 부분이며, 최초에 단 한번만 실행됩니다. 일반적으로 반복문에서 사용되는 변수 선언을 하는 용도로 가장 많이 사용합니다.

2️⃣ 번 - Conditional / 조건부 구절

반복문의 반복 구절(3번)의 실행 여부를 결정하는 조건이 들어가는 부분입니다. 조건부 구절(2번)의 조건이 성립하지 않는다면, 반복문의 실행은 즉시 종료됩니다. 조건 성립 여부는 조건부 구절(2번)의 결과값이 Truthy인지 Falsy인지를 의미합니다.

3️⃣ 번 - Repeat / 반복 구절

반복하고 싶은 로직을 작성하는 공간입니다.

4️⃣ 번 - Update / 업데이트 구절

반복 구절(3번)이 끝난 직후에 바로 이어서 실행되는 구절입니다. 반복구절(3번)이 5번 실행된다면, 업데이트 구절(4번) 또한 5번 실행됩니다.

실행 순서

1~4번 구절에 대한 상세 내용을 예제와 함께 살펴보겠습니다.

for (let i = 1; i < 3; i++) {
  console.log(i);
}
  1. 1번 초기화 (Initialization) 실행

    • 변수 i를 선언하고 1이라는 숫자값을 할당합니다.

  2. 2번 조건부 구절 (Conditional) 실행 및 결과 Truthy / Falsy 판단

    • i < 3를 실행하고, 현재 i는 1이므로 결과는 true입니다.

    • Truthy 값이 나왔으므로 3번 반복 구절이 실행될 수 있습니다.

  3. 3번 반복 구절이 실행됩니다.

    • i의 값을 콘솔에 출력합니다.

    • 현재 i는 1이므로 1을 출력합니다.

  4. 3번 반복 구절이 끝났으므로 4번 업데이트 구절이 실행됩니다.

    • i++를 실행하고, i의 값이 2로 증가합니다.

  5. 2번 조건부 구절 (Conditional) 실행 및 결과 Truthy / Falsy 판단

    • i < 3을 실행하고, 현재 i는 2이므로 결과는 true입니다.

    • Truthy 값이 나왔으므로 3번 반복 구절이 실행될 수 있습니다.

  6. 3번 반복 구절이 실행됩니다.

    • i의 값을 콘솔에 출력합니다.

    • 현재 i는 2이므로 2을 출력합니다.

  7. 3번 반복 구절이 끝났으므로 4번 업데이트 구절이 실행됩니다.

    • i++를 실행하고, i의 값이 3으로 증가합니다.

  8. 2번 조건부 구절 (Conditional) 실행 및 결과 Truthy / Falsy 판단

    • i < 3을 실행하고, 현재 i는 3이므로 결과는 false입니다.

    • Falsy 값이 나왔으므로 3번 파트가 실행될 수 없습니다.

  9. 반복문이 즉시 종료됩니다.

반복문 중단하기

for loop 내부에서 우리는 언제라도 원하는 상황에 break라는 키워드를 사용하여 반복문의 흐름을 빠져나올 수 있습니다.

break 키워드는 반복 구절 내부에서 사용할 수 있고, break 구문이 실행되게 되면, 반복문이 즉시 종료되게 됩니다. 아래의 예제를 한번 살펴봅시다.

console.log('before for loop');

for (let i = 1; i < 11; i += 2) {
  console.log(i);
}

console.log('after for loop');

위 예제를 실행하게 되면, 1부터 10까지 홀수가 콘솔에 나타나게 됩니다. 그렇다면 아래와 같이 변경하면 어떻게 될까요?

console.log('before for loop');

for (var i = 1; i < 11; i += 2) {
  if (i === 7) {
    break;
  }

  console.log(i);
}

console.log('after for loop');

반복 구문 내부에 새로운 조건이 추가되었습니다. i의 값이 7과 같을 경우, break를 실행하게 됩니다. 그리고 더 이상 반복문은 실행되지 않고, after for loop이 콘솔에 나타났습니다. 즉, break 실행문이 실행되어 for loop모두 종료되게 된 것입니다.

반복 구절 단위로 종료하기

위에서 말씀드린 break 구문은 반복문 전체를 종료시켰습니다. 이번에는 continue를 이용하여 반복 구절 단위로 종료시키는 방법을 살펴보겠습니다.

텍스트로 이해가 잘 안될 수 있으니, 반드시 실행시켜보세요.

console.log('before for loop');

for (let i = 1; i < 11; i += 2) {
  if (i === 7) {
    continue;
  }

  console.log(i);
}

console.log('after for loop');

위 예제 코드의 경우, 1, 3, 5, 9가 출력됩니다. 7의 경우에는 continue 구문이 실행되었기 때문에 반복 구절을 종료하게 되었습니다. 하지만 전체 반복문을 종료시킨 것은 아닙니다. 그렇기에 다시 업데이트 구절 -> 조건 구절 -> 반복 구절이 실행되어 9가 출력되게 되었습니다.

우리가 살펴본 반복문 외에도 다양한 반복문의 종류가 있습니다. 하지만 지금은 가장 기본적인 반복문을 활용하여 논리 전개에 대한 훈련에 집중하는게 더욱 이상적입니다. 하나의 반복문을 잘 익히면 다른 반복문을 사용하는 것은 어렵지 않습니다.

응용해보기

const name = "ken";

반복문을 이용하여 주어진 문자열 name 의 알파벳을 역순으로 한 글자씩 출력하는 코드를 작성해보세요. name 변수의 문자열 값이 길어지거나 짧아지는 등 바뀌더라도 반복문은 잘 동작해야 합니다.

1부터 100까지 모든 숫자를 출력하세요. 단, 조건이 있습니다. 단, 3의 배수는 "삼삼이"라고 출력하세요.

5의 배수는 "초롱이"라고 출력하세요.

15의 배수는 "초3"이라고 출력하세요.

나머지는 그냥 숫자를 출력하세요.

위와 같은 문제를 해결하는 과정에서는 반드시 하나씩 해결하세요. 동시에 여러개의 조건을 동시다발적으로 접근하지 마세요. 정신 사납습니다. 🧐

Last updated