5장 제어 구조

이제 변수를 어떻게 사용하는지 알았으니 다소 유용한 프로그램을 작성해볼 차례다. 먼저 1부터 시작해 10까지 세면서 각 숫자를 한 줄씩 출력하는 프로그램을 작성해 보자. 지금까지 배운 내용을 이용하면 다음과 같이 작성할 수 있다.

package main

import "fmt"

func main() {
    fmt.Println(1)
    fmt.Println(2)
    fmt.Println(3)
    fmt.Println(4)
    fmt.Println(5)
    fmt.Println(6)
    fmt.Println(7)
    fmt.Println(8)
    fmt.Println(9)
    fmt.Println(10)
}

또는 다음과 같이 작성할 수도 있다.

package main

import "fmt"

func main() {
    fmt.Println(`1
2
3
4
5
6
7
8
9
10`)
}

하지만 이 두 프로그램 모두 작성하기가 꽤나 지겨울 것이다. 우리에겐 뭔가를 여러 번에 걸쳐 할 수 있는 방법이 필요하다.

5.1 For

for 문을 이용하면 여러 문장(블록)을 여러 번에 걸쳐 반복할 수 있다. 앞의 프로그램을 for 문을 이용해 재작성하면 다음 코드와 같다.

package main

import "fmt"

func main() {
    i := 1
    for i <= 10 {
        fmt.Println(i)
        i = i + 1
    }
}

먼저 출력하고 싶은 숫자를 저장하는 데 사용하는 i라는 변수를 만들었다. 그런 다음 for라는 키워드를 이용해 for 루프를 작성했는데, true이거나 false가 되는 조건식을 지정하고, 마지막으로 실행할 블록을 작성했다. for 루프는 다음과 같이 동작한다.

  1. i <= 10("i는 10보다 작거나 같다")이라는 수식을 평가(실행)한다. 이것의 평가 결과가 참이면 블록 안의 문장을 실행한다. 그렇지 않으면 블록 이후에 나오는 다음 줄로 이동한다(이 경우 for 루프 이후에 아무것도 없으므로 프로그램이 종료했다).
  2. 블록 안의 문장을 실행하고 나면 for 문의 처음으로 되돌아가 1단계부터 반복한다.

i = i + 1이라고 적힌 줄은 굉장히 중요한데, 이 부분이 없으면 i <= 10이 항상 true로 평가되어 프로그램이 멈추지 않을 것이기 때문이다(이러한 경우를 무한 루프라 한다).

연습 삼아 컴퓨터가 하는 것처럼 프로그램을 차례대로 실행해 보자.

다른 프로그래밍 언어에는 다양한 종류의 루프(while, do, until, foreach, ...)가 있지만 Go에서는 다양한 방식으로 사용할 수 있는 단 하나의 루프만 제공한다. 앞의 프로그램은 다음과 같은 식으로도 작성할 수 있었다.

func main() {
    for i := 1; i <= 10; i++ {
        fmt.Println(i)
    }
}

이제 조건식에도 두 가지 다른 문장이 세미콜론으로 구분되어 포함돼 있다. 먼저 변수 초기화 구문이 나오고, 다음으로 매번 검사할 조건이 나오며, 마지막으로 변수를 "증가시킨다"(변수에 1을 더하는 것은 굉장히 자주 있는 일이라서 이를 위한 특별한 연산자인 ++이 있다. 이와 비슷하게 1을 빼는 것도 --로 할 수 있다).

이후 장에서는 for 루프를 이용하는 또 다른 방법을 보게 될 것이다.

5.2 If

앞에서 작성한 프로그램을 수정해서 각 줄에 1~10에 해당하는 숫자를 출력하는 대신 다음과 같이 각 숫자가 짝수인지 홀수인지도 출력하도록 만들어 보자.

1 홀수
2 짝수
3 홀수
4 짝수
5 홀수
6 짝수
7 홀수
8 짝수
9 홀수
10 짝수

먼저 어떤 숫자가 짝수인지 홀수인지 판별하는 방법이 필요하다. 이를 파악하는 손쉬운 방법은 숫자를 2로 나눠보는 것이다. 2로 나눴을 때 나누어 떨어지면 짝수이고, 그렇지 않으면 홀수다. 그럼 Go에서는 나머지를 어떻게 구할 수 있을까? % 연산자를 쓰면 된다. 1 % 21이고, 2 % 20이며, 3 % 21과 같은 식이다.

다음으로 조건에 따라 서로 다른 코드를 실행하는 방법이 필요하다. 이 경우 if 문을 이용하면 된다.

if i % 2 == 0 {
    // 짝수
} else {
    // 홀수
}

조건 다음에 블록이 이어진다는 점에서 if 문은 for 문과 비슷하다. 필요할 경우 if 문에는 else 부분도 지정할 수 있다. 조건이 true로 평가되면 조건 다음에 나오는 블록이 실행되고, 그렇지 않을 경우 블록을 건너뛰거나 else 블록이 있을 경우 해당 블록이 실행된다.

if 문에는 else if 부분도 있을 수 있다.

if i % 2 == 0 {
    // 2로 나눌 수 있음
} else if i % 3 == 0 {
    // 3으로 나눌 수 있음
} else if i % 4 == 0 {
    // 4로 나눌 수 있음
}

각 조건은 위에서 아래로 검사되며, 첫 번째 조건이 참이면 그와 관련된 블록이 실행된다. 그럼 나머지 블록은 아무것도 실행되지 않으며, 나머지 블록의 조건들이 통과하더라도 마찬가지다(예를 들어 8은 4와 2로 나눌 수 있지만 // 4로 나눌 수 있음 블록은 결코 실행되지 않을 텐데, // 2로 나눌 수 있음 블록이 먼저 실행되기 때문이다).

지금까지 배운 내용을 모두 종합하면 다음과 같다.

func main() {
    for i := 1; i <= 10; i++ {
        if i % 2 == 0 {
            fmt.Println(i, "짝수")
        } else {
            fmt.Println(i, "홀수")
        }
    }
}

이 프로그램을 차례대로 실행해 보자.

초등학교 이후로는 좀처럼 보기 힘든 나머지 연산자는 프로그래밍할 때 굉장히 유용하다. 테이블에 줄무늬를 넣는 것부터 데이터 집합을 분할하는 것까지 어디서든 이 연산자를 보게 될 것이다.

5.4 Switch

각 숫자에 대한 한글 이름을 출력하는 프로그램이 필요하다고 해보자. 지금까지 배운 내용을 이용하면 다음과 같은 코드로 시작할 수도 있다.

if i == 0 {
    fmt.Println("영")
} else if i == 1 {
    fmt.Println("일")
} else if i == 2 {
    fmt.Println("이")
} else if i == 3 {
    fmt.Println("삼")
} else if i == 4 {
    fmt.Println("사")
} else if i == 5 {
    fmt.Println("오")
}

프로그램을 이런 식으로 작성하려면 꽤나 지겹기 때문에 Go에서는 이를 더 손쉽게 만들어주는 switch라는 구문을 제공한다. 앞의 프로그램은 다음과 같이 재작성할 수 있다.

switch i {
case 0: fmt.Println("영")
case 1: fmt.Println("일")
case 2: fmt.Println("이")
case 3: fmt.Println("삼")
case 4: fmt.Println("사")
case 5: fmt.Println("오")
default: fmt.Println("알 수 없는 숫자")
}

switch 문은 switch라는 키워드로 시작한 후 수식이 나오고(이 경우 i) 각 case가 연속해서 나온다. 수식의 값은 각 case 키워드 다음에 나오는 수식과 비교된다. 두 수식의 값이 일치하면 : 다음에 나오는 문장(들)이 실행된다.

if 문과 마찬가지로 각 케이스는 위에서 아래로 검사되고 가장 먼저 수식의 값이 일치하는 케이스가 선택된다. switch 문에서는 값이 일치하는 케이스가 없을 경우 실행될 기본 케이스도 지원한다(if 문의 else와 비슷하다고 보면 된다).

지금까지 알아본 내용이 주요 제어 흐름 구문이다. 추가적인 구문은 이후 장에서 설명하겠다.

연습 문제

  1. 다음 프로그램의 출력 결과는 무엇인가?

    i := 10
    if i > 10 {
        fmt.Println("크다")
    } else {
        fmt.Println("작다")
    }
    
  2. 1과 100 사이의 숫자 중 3으로 나누어 떨어지는 수(3, 6, 9, ...)를 모두 출력하는 프로그램을 작성하라.

  3. 1에서 100까지 출력하는 프로그램을 작성하라. 3의 배수에 대해서는 숫자 대신 "Fizz"를 출력하고 5의 배수에 대해서는 "Buzz"를 출력하라. 3과 5의 공배수에 대해서는 "FizzBuzz"를 출력하라.

← 이전다음 →