본문 바로가기
Program Language/Kotlin

[Do it! 코틀린 프로그래밍] 4. 프로그램의 흐름 제어

by SungJe 2021. 4. 5.

4. 프로그램의 흐름 제어


1. 조건문

조건문은 주어진 조건에 따라 다른 결과를 반환하는 코드이다. 코틀린에서는 제어문들을 간략하게 사용할 수 있는 표현이 많다.

  • if문과 if~else문
/* 구조 */
if (조건식) {
    수행할 문장 // 조건식이 true인 경우에만 수행
} else {
    수행할 문장 // 조건식이 false인 경우에 수행
}

var max: Int
if (a > b) {
    max = a
} else {
    max = b
}

/* 위 조건문을 간략화한 표현식 */
val max = if (a > b) a else b
  • else if문으로 조건문 중첩하기
val score = readLine()?.toDouble() ?: 0.0
var grade: Char = 'F'

if (score >= 90.0) {
    grade = 'A'
} else if (score >= 80.0 && score <= 89.9) {
    grade = 'B'
} else if (score >= 70.0 && score <= 79.9) {
    grade = 'C'
}
println("Score: $score, Grade: $grade")

/* 위 조건문을 in 연산자와 범위 연산자로 조건식 간략화 */
if (score >= 90.0) {
    grade = 'A'
} else if (score in 80.0..89.9) {
    grade = 'B'
} else if (score in 70.0..79.9) {
    grade = 'C'
}
  • when문으로 다양한 조건 처리하기
/* 구조 */
when (인자) {
    인자에 일치하는 값 혹은 표현식 -> 수행할 문장
    인자에 일치하는 범위 -> 수행할 문장
    ...
    else -> 수행할 문장
}

fun typeCheck(obj: Any) {
    when (obj) {
        is Int -> println("Int: $obj")
        is String -> println("String: $obj")
        !is String -> println("Not a String")
        else -> println("Unknown")
    }
}

typeCheck(1) // Int: 1
typeCheck("Hello") // String: Hello
typeCheck('A') // Not a String

2. 반복문

  • for문
/* 구조 */
for (요소 변수 in 컬렉션 또는 범위) { 반복할 본문 }

/* 상향식 */
var sum = 0
for (num in 1..10) sum += num
println("Sum: $sum") // 55

/* 하향식 */
var sum = 0
for (num in 10 downTo 1) sum += num
println("Sum: $sum") // 55

/* step 키워드 사용으로 홀수 덧셈 */
var sum = 0
for (num in 1..10 step 2) sum += num
println("Sum: $sum") // 25
  • while문
/* 구조 */
while (조건식) { // 조건식이 true인 동안 본문의 무한 반복
    본문
    ...
}

/* while문으로 팩토리얼 계산 */
var number = readLine()?.toInt() ?: 0
var factorial: Long = 1

while (number > 0) {
    factorial *= number
    number -= 1
}
println("Factorial: $factorial")
  • do~while문
/* 구조 */
do {
    본문
    ...
} while (조건식)

/* 1부터 N까지 덧셈 */
do {
    println("Enter an integer: ")
    val n = readLine()?.toInt ?: 0
    var sum = 0

    for (num in 1..n) {
        sum += num
    }
    if (sum != 0) println("Sum: $sum")
} while (n != 0)

NOTE✏️

  • 컬렉션(Collection): Array, List, Map 등의 여러 데이터를 다루는 요소를 말한다. 이것은 모두 이터레이터(Iterator)라는 반복을 위한 인터페이스를 구현한다.

3. 흐름의 중단과 반환

흐름 제어문

  • return: 함수에서 결괏값을 반환하거나 지정된 라벨로 이동
/* 람다식에서 return문 사용 */
inline fun inlineLambda(a: Int, b: Int, out: (Int, Int) -> Unit) {
    out(a, b)
}

fun retFunc() {
    println("start of retFunc")
    inlineLambda(13, 3) lable@{ a, b -> // 라벨 지정
        val result = a + b
        if (result > 10) return@lable // 라벨 생략시 비지역 반환 발생
        println("result: $result")
    } // 이 부분으로 빠져나감
    println("end of retFunc")
}
  • break: for문이나 while문의 조건식에 상관없이 반복문을 종료
  • continue: for문이나 while문의 본문을 모두 수행하지 않고 다시 조건식으로 이동
/* 구조 */
for (반복 조건) { // continue문
    ...
    if (중단 조건) {
        continue // 반복문의 조건식으로 이동
    }

    if (중단 조건) {
        break // 반복문을 종료
    }
    ...
} // break문

/* 라벨과 함께 사용 */
fun labelBreak() {
    var sum = 0
    first@ for (i in 1..10) {
        second@ for (j in 1..10) {
            if (i < j) {
                /* 가까운 반복문(second@)이 아닌 지정된 라벨의 조건식으로 이동 */
                continue@first
            }
            sum += j
        }
    }
    println("Sum: $sum") // Sum: 220
}

예외 처리문

  • try {...} catch {...}: try 블록의 본문을 수행하는 도중 예외가 발생하면 catch 블록의 본문을 실행
  • try {...} catch {...} finally {...}: 예외가 발생해도 finally 블록 본문은 항상 실행
/* 구조 */
try {
    예외 발생 가능성 있는 문장
} catch (e: 예외 처리 클래스 이름) {
    예외를 처리하기 위한 문장
} finally {
    반드시 실행되어야 하는 문장
}

/* 0으로 나누기 예외 처리 */
try {
    val result = 3 / 0 // 예외 발생
    println(result) // 실행되지 않음
} catch (e: ArithmeticException) {
    println("Exception is handled: ${e.message}")
    e.printStackTrace() // 스택 추적
} finally {
    println("finally 블록은 항상 실행")
}

/* 사용자 정의 예외 발생시키기 */
class InvalidNameException(message: String) : Exception(message) // 사용자 예외 클래스

fun validateName(name: String) {
    if(name.matches(Regex(".*\\d+.*"))) { // 이름에 숫자가 포함되어 있으면 예외를 발생시킴
        throw InvalidNameException("Your name: \"$name\" contains numberals.")
    }
}

val name = "sungje365"
try {
    validateName(name)
} catch (e: InvalidNameException) {
    println(e.message)
} catch (e: Exception) { // 기타 예외 처리
    println(e.message)
}

NOTE✏️

  • 정규식(Regular Expression): 특정한 규칙을 가진 문자열로 어떤 문자열에서 정해진 패턴을 알아낼 때 자주 사용 Link