[인생 프로그래밍] 반복문 (Loop statement)

Rex·2022년 1월 18일
0

인생 프로그래밍

목록 보기
21/33

반복문 (Loop statement)

우리가 보는 하늘에는 매일 반복적으로 해가 뜬다. 우리의 일상은 특별한 사건이 일어나지 않으면 대부분의 경우 매일/매주/매달/매년 반복된다. 물론 그 속에 내용은 조금씩은 다르기 때문에 우리의 하루하루는 기쁘기도, 슬프기도, 화내기도, 즐겁기도, 행복하기도 하다. 매일이 비슷하게 느껴지겠지만 오늘은 늘 최고의 날이라고 생각하고 내일은 늘 새로운 날이라고 생각해 보자. 인생이 훨씬 활기 차질 것이다.

좋아하는 음악을 여러 번 반복해서 듣고 싶을 때, 프린터로 똑같은 문서를 여러 장 인쇄할 때, 수많은 물건들을 비교할 때, 내가 원하는 중고 물건이 올라왔는지 확인할 때 등 우리의 삶에는 반복적으로 하는 일들이 참 많다.

대부분의 반복은 특정 목적을 달성할 때까지 지속한다. 좋아하는 음악은 듣고 싶을 때 재생되고 충분히 들었다면 중지할 것이며, 문서의 인쇄는 원하는 양이 나오면 중단하게 된다. 수많은 물건들을 비교하다가 나의 기준에 맞는 물건이 있다면 선택하여 반복을 멈출 것이고, 내가 원하는 중고 물건이 내가 원하는 가격에 올라와서 구매한다면 더 이상 이 물건에 대한 확인을 반복하지 않을 것이다.

우리의 삶에도 반복되는 부분이 너무나도 많기 때문에 프로그래밍에서도 반복문(Loop statement) 이라는 게 있다. 반복문은 영어로 '루프(Loop)' 라고 부른다. 인간은 반복하는 행위를 아주 힘들어하지만 컴퓨터는 매우 잘한다. 그래서 우리는 컴퓨터의 반복 능력을 반드시 활용할 필요가 있다.


1. 'for' loop

반복문에는 2가지 종류가 있다.

  1. 횟수가 정해져 있는 반복: for loop
  2. 횟수가 정해져있지 않은 반복: while loop

for loop 는 주로 횟수가 정해져있을 때 사용하는 반복문이다. 코드를 보자.

for num in range(0, 10):  # 0부터 9까지 숫자를 하나씩 출력
    print(num)

위 코드에서 range(0, 10) 함수는 0부터 9까지의 범위(range)를 return 해주는 함수이다. 우리는 그 range 값을 이용해서 총 10번 반복되는 for loop 을 실행할 수 있다.


2. 'while' loop

while loop 는 주로 횟수가 정해져있지 않을 때, 횟수를 예측하기 어려울 때 사용하는 반복문이다.

num = 0

while (num < 10):  # boolean 값이 True 인 동안에는 무한 반복 / False 가 되는 즉시 반복문 종료됨.
    print(num)
    num += 1

위 코드는 위의 for loop 에서 사용한 코드와 실행 결과가 완전히 똑같다.

이 예시는 while loop 으로 for loop 을 완전히 대체할 수 있다는 것을 보여준 건데, 그 차이를 보면 for 문은 특정 범위(range) 값을 기준으로 반복되고, while 문은 boolean 값이 True 상태인 동안에 실행하는 것이 특징이다.

num = 0

while (True):  # 무한 루프(infinite loop)
    print(num)
    num += 1

    if (num > 9):  # 탈출 조건: 숫자 9보다 큰 경우
        break  # 반복문 탈출

우리가 프로그램 내에서 탈출 조건을 명시하지 않은 반복문을 사용할 경우, 프로그램이 종료되지 않고 영원히(컴퓨터가 다운될 때까지) 반복문 속에 갇히게 된다. 이를 '무한 루프 (Infinite loop)' 라고 한다.

반복문을 설명하면서 "대부분의 반복은 특정 목적을 달성할 때까지 지속한다." 라고 했다. 내가 원하는 조건이 만족되었을 때 반복문을 탈출하는 방법은 바로 break 키워드를 사용하는 것이다. (JavaScript 에서는 switch 문에서도 사용한다.) 만약 몇 회를 반복해야 할지 알 수 없고, 특정 조건이 발생했을 때 반복문을 탈출해야 한다면 break 키워드를 사용하면 된다.

여기서 꼭 알아둬야 할 필수 지식!
이미 실행된 프로그램에서 무한 루프에 갇히게 되면 이를 통제할 수가 없다. 무한 루프가 진행되면 어느 순간부터 컴퓨터가 반응이 없어지고, 비행기가 이륙하듯 쿨링팬이 막 돌기 시작할 것이다. 이 상태로 오랫동안 놔두면 컴퓨터에게 부담이 될 수 있으니 프로그램을 강제로 종료해야 한다. 터미널에서 프로그램을 강제로 종료하는 방법은 control + c 를 누르는 것이다. (Mac OS 동일)


break & continue 키워드

breakcontinue 는 반복문을 컨트롤하는데 유용하게 쓰이는 키워드이다. 이 두 가지 키워드를 꼭 알아두어야 한다.

break 는 반복문(for, while)을 탈출하는데 유용하게 사용하는 키워드이다. break 는 조금 전에 사용해 봤으니 이해가 됐을 것이다. break 는 자신을 감싸고 있는 영역을 즉시 탈출하는 기능을 한다.

continue 는 현재 반복 사이클을 중단하고, 바로 다음 반복 사이클로 넘어가는 기능을 수행해요. 현재 반복 사이클을 '스킵' 한다고 이해하면 된다.

for num in range(0, 10):  # 0부터 9까지 숫자를 하나씩 반복
    if (2 < num and num < 9):  # 2보다 크고 9보다 작은 수는
        continue  # 스킵
    print(num)  # 스킵 하지 않았다면 콘솔에 출력됨

위 코드를 실행해 보면, 콘솔의 결과가 0 1 2 9 로 출력되는 것을 볼 수 있다. 그 이유는 0부터 9까지의 숫자를 반복하면서, 2보다 크고 9보다 작은 수(3~8)는 continue 키워드를 통해서 남은 코드를 실행하지 않고, 다음 반복 횟수로 넘어가버렸기 때문이다. 이처럼 breakcontinue 는 반복문을 마음대로 컨트롤하는데 큰 도움을 주는 키워드이니 꼭 알아두어야 한다.


반복문의 중첩 (Nested loop)

프로그래밍은 문법에만 맞으면 상상하는 대로 코딩이 가능하다. 반복문 안에 반복문을 여러 개 넣을 수도 있고, 조건문 안에 조건문을 여러 개 넣을 수도 있다. 인생에도 이렇게 반복문 속에 반복문이 필요한 경우가 많다. 대표적인 예시로 구구단이 있다.

2단부터 시작해서 1~9까지 곱하고, 3단, 4단 ... 8단을 거쳐서 9단까지 계속해서 반복하며 곱한다. 중첩 반복문의 아주 훌륭한 예시이다. 이를 코드로 작성하여 오랜만에 구구단을 복습해 보자.

# 구구단 출력하기
for x in range(2, 10):  # 2부터 9까지 숫자를 하나씩 출력
    for y in range(1, 10):  # 1부터 9까지 숫자를 하나씩 출력
        print(f'{x} * {y} == {x * y}')

        if (y == 9):
            print('')  # 빈 줄을 출력

재귀 함수 (Recursive Function)

재귀 함수라는 글자가 좀 어려워 보일 수 있는데, 풀어서 쓰면 '다시 돌아오는(재귀, 再歸) 함수' 라는 뜻이다. 함수 자기 자신을 실행하는 함수라는 이야기다. 자기 자신을 실행하기 때문에 별도의 탈출 조건을 설정하지 않으면 무한히 자기 자신을 반복하여 실행하게 된다. 이는 반복문과 매우 흡사하게 동작한다. 그러나 재귀 함수는 함수일 뿐, 반복문이 아니므로 break, continue 키워드를 사용할 수 없다.

재귀 함수는 반복문과 성격이 비슷하여 반복문 파트에 넣으려고 했지만, 함수에 대한 이해가 바탕이 되어야 하기에 여기에서 다룬다.

백문이 불여일타! 바로 코드를 작성하고 실행해 보자.

def my_fn(num):  # 함수 선언
    print(num)
    my_fn(num + 1)  # 자기 자신의 함수를 다시 호출 (재귀 함수 호출)
    
my_fn(1)  # 처음으로 함수 호출

위 코드를 실행해 보면 1부터 999 정도까지 반복된 다음에 RecursionError: maximum recursion depth exceeded while calling a Python object 라는 오류가 발생한다. 이 오류는 Python 객체를 호출하는 동안 최대 재귀 깊이가 초과되었습니다. 라는 뜻으로, 이전에 배운 무한 루프를 사용했을 때처럼 영원히 갇힐 뻔 했으니 탈출 조건을 설정해야 한다는 의미다. 그러면 탈출 조건을 만들어보자.

def my_fn(num):  # 함수 선언
    print(num)
    if (num == 200):  # 탈출 조건
        return        # 함수 종료
    my_fn(num + 1)  # 자기 자신의 함수를 다시 호출

my_fn(1)  # 처음으로 함수 호출

이번에는 1부터 200까지만 실행되고 재귀 함수가 종료될 것이다.

재귀 함수는 먼저 이야기했듯이, 자기 자신을 다시 실행하는 함수일 뿐, 반복문은 아니기 때문에 continue 또는 break 키워드를 사용할 수 없다. 자신의 함수를 다시 호출하는 것으로 continue 의 역할을 하고, 함수를 return 하는 것으로 break 의 역할을 대신 할 수 있다.

재귀 함수는 반복문과 비슷하게 느껴지지만, 단순 반복이 아닌 보다 특징적인 문제 해결 영역에 사용된다. 조금 추상적으로 말하자면 깊이감이 있는 반복적인 일에 유용하다. 예를 들어, 무수히 많은 폴더 안에 들어있는 my.txt 라는 파일을 찾는다고 생각해 보자.

폴더를 하나 열면 그 안에 다른 폴더들과 파일들이 있을 수 있고,
거기서 어떤 폴더를 열면 그 안에 다른 폴더들과 파일들이 있을 수 있고,
거기서 어떤 폴더를 열면 그 안에 다른 폴더들과 파일들이 있을 수 있고,
거기서 어떤 폴더를 열면 그 안에 다른 폴더들과 파일들이 있을 수 있고,
거기서 어떤 폴더를 열면 그 안에 다른 폴더들과 파일들이 있을 수 있고...

이런 식으로 계속 반복적으로 찾아야만 할 것이다. 이렇게 깊이감이 있는 반복적인 상황에 매우 유용하게 쓰이는 것이 바로 재귀 함수이다!


JavaScript 의 반복문

JavaScript 의 기본적인 반복문은 총 5가지가 있다.

  1. while
  2. do while
  3. for
  4. for in
  5. for of

그리고 반복문은 아니지만 특정 로직을 반복할 수 있도록 구현하는 방법은 3가지가 더 있다.

  1. 재귀 함수
  2. setInterval() 함수
  3. setTimeout() 함수 - 응용 필요

너무 많아서 당황스러운가? 인생에 정말 다양한 상황들이 존재하듯이, 그 다양한 문제들을 적절하게 해결하기 위해 다양한 기능들이 만들어져 있다. 그렇지만 이 책에서는 반복문의 핵심만을 다루기 위해서, 위의 파이썬과 마찬가지로 기본적인 while 문 / for 문 만 사용할 것이다. 그 두 가지 만으로도 대부분의 케이스는 해결할 수 있다.

JavaScript 의 'for' loop

for (let num = 0; num < 10; num++) {
    console.log(num);  // 0부터 9까지 숫자를 하나씩 출력
}

Python 과 조금 방식이 다른데, 구조를 설명하자면 아래와 같다.

for ([초기문]; [조건문]; [증감문]) {
    ...로직...
}

먼저 초기문을 통해 반복문 내에서 사용할 변수를 초기화하고, 조건문이 true 인 동안에 반복문을 수행하며, 반복문이 한 사이클 완료될 때마다 증감문이 실행되는 구조이다. 그래서 숫자가 0, 1, 2, 3 ... 식으로 올라간다.

JavaScript 의 'while' loop

while 문은 파이썬, 자바스크립트, 자바 모두 거의 비슷하다.

let num = 0;

while (num > 9) {  // boolean 값이 true 인 동안에는 무한 반복 / false 가 되는 즉시 반복문 종료됨.
    console.log(num);
    num += 1;
    // num++;  이라고 작성해도 결과는 동일함
}

JavaScript 의 infinite loop

let num = 0;

while (true) {  // 무한 루프(infinite loop)
    console.log(num);
    num++;
    if (num > 9) {  // 탈출 조건
        break;  // 반복문 탈출
    }
}

정리하기

  1. 반복문의 종류
    • for, while
    • for: 반복 횟수가 정해져 있는 경우에 유용
    • while: 반복 횟수가 정해져 있지 않은 경우에 유용
  2. break, continue
    • 반복문을 탈출하거나, 현재 반복 단계를 스킵 하는데 사용되는 키워드

생각 해보기

우리의 일상에서 특정 조건을 만족할 때까지 반복해야 하는 일들을 생각해 보자. 그리고 그것을 프로그래밍에 담아보려고 노력해 보자.

"우리의 삶에서 반복되는 다양한 것들을 눈여겨 본다면 프로그래밍으로 삶을 더 이롭게 만들 수 있다."


연습 문제

다음 과정을 시작하기 전에 풀어보길 권장하는 문제이다. 이 문제를 해결하지 못하더라도 다음 과정으로 넘어갈 수 있지만, 풀어낸다면 정말 큰 학습이 될 것이다. 어렵지 않으니까 천천히 읽고 구현해 보자.

반복문을 배우면 모두가 한 번쯤 풀어보는 문제가 있다. 이름하여 '별 찍기' 문제!
반복문의 중첩 (Nested loop) 을 활용해서 콘솔 창에 아래와 같은 형태의 출력이 나오도록 구현해 보자.

**********
**********
**********
**********
**********

파이썬의 경우, 단순히 print('*') 만 사용하면 줄바꿈이 자동으로 일어나는데, print() 함수 내에 end='' 를 추가하면 줄바꿈 없이 출력할 수 있다.
Python 의 경우: print('*') 대신, 이 코드를 사용하라: print('*', end='')
JavaScript 의 경우: console.log() 함수 대신, process.stdout.write() 함수를 사용하라.

  • 지금 Python 과정을 하고 있다면, Python 으로 풀어야 한다.
  • Python 과정을 모두 마치고 JavaScript 를 시작했다면, JavaScript 로 풀어야 한다.
  • 너무 어려우면 ChatGPT 에게 도움을 요청하자.

궁금증 / 질문 / 개선점이 있다면 꼭 댓글을 달아주세요. 제가 최선을 다해 도와드리겠습니다. 여러분들의 최고의 학습 친구가 되어드리겠습니다.

#인생프로그래밍 #개발자렉스 #프로그래밍 #프로그래머 #개발자 #개발입문 #프로그래밍입문서적 #코딩교육 #코딩무료교육 #파이썬 #자바스크립트 #자바 #파이썬기초 #파이썬독학 #파이썬책 #혼자공부하는파이썬 #혼공파 #자바스크립트책 #앱개발 #어플개발 #ProgrammingOfLife #programming #programmer #coding #software #developer #python #javascript #java

profile
🔥 from Abstraction to Realization

0개의 댓글