본문 바로가기

Study/Kotlin Study

[Kotlin] 조건문

+ 항공대학교 김철기 교수님의 객체 지향 프로그래밍 과목 내용를 정리한 글입니다.

if 문

- 조건문은 반드시 Boolean 타입이어야 한다.

fun max(a: Int, b: Int): Int {
    if (a > b) return a // a가 b보다 크면 a를 반환
    else return b // 그렇지 않으면 b를 반환
}
/* fun max(a: Int, b: Int): Int = if (a > b) a else b */

fun main(args: Array<String>) {
    // args는 String 배열
    if (args.isNotEmpty()) { // args가 비어 있지 않다면
        val message = "Hello, ${args[0]}"
        println(message)
    }
    else {
        println()
    }
}

식 표현을 위한 if ~ else문

- 식 표현에 여러 줄 연산을 포함할 수도 있다. 이 경우 마지막 문장의 값을 이용한다.

fun main() {
    val s = readLine()!! // s는 널 값이 아닌 String
    val i = s.indexOf("/")
    // i는 s에 '/'가 존재하는 인덱스 (없다면 -1 반환)

    val result = if (i >= 0) { // i가 0 이상이라면 (s에 '/'가 있다면)
        val a = s.substring(0, i).toInt() // s 문자열의 0 ~ i-1 인덱스까지 추출하고 Int형으로 변환 후 저장
        val b = s.substring(i + 1).toInt() // s 문자열의 i+1 ~ 끝 인덱스까지 추출하고 Int형으로 변환 후 저장
        (a / b).toString() // a 와 b를 나눈 값을 String형으로 변환
        // return을 사용하지 않았으므로 마지막 문장인 (a / b).toString() 값이 result에 저장
    } else "" // s에 '/'가 없다면 (i가 -1인 경우) 마지막 문장인 ""값이 result에 저장
    
    println(result)
}

if 문에서 식과 return 문 혼용하기

fun renamePackage(fullName: String, newName: String): String {
    val i = fullName.lastIndexOf('.') // 마지막 '.'의 인덱스 반환
    val prefix = if (i >= 0) fullName.substring(0, i + 1) else return newName // .이 없다면 바로 함수 종료 후 반환
    // 식 표현에서 return을 사용하는 것도 가능하다.
    return prefix + newName
}

fun main() {
    val package_name = readLine()!!
    println(renamePackage(package_name, "newName"))
}

범위 타입

- 범위 (range)를 표현하기 위한 타입 (..)

fun main() {
    val chars = 'a'..'h' // 'a'에서 'h'까지의 모든 문자
    val two_digits = 10..99 // 10부터 99까지의 모든 정수
    val zero2One = 0.0..1.0 // 0부터 1까지의 모든 부동소수점 수

    println(chars) // a..h
    println(two_digits) // 10..99
    println(zero2One) // 0.0..1.0
}

- in 연산: 특정 값이 범위에 포함되는지를 판단하는 연산

fun main() {
    val num = readLine()!!.toInt()
    println(num in 10..99) // num >= 10 && num <= 99
    //num이 10 ~ 99 안의 정수라면 true 출력, 아니면 false 출력
    println(num !in 10..99) // !(num in 10..99) 조건과 같다
    //num이 10 ~ 99 안의 정수라면 false 출력, 아니면 true 출력

    val str = readLine()!!
    println(str in "abc".."xyz") // 문자열도 범위 비교 가능
    // str이 "abc" ~ "xyz" 아스키코드 범위 내에 있으면 true, 아니면 false 출력
}

until, downTo, step

- until

fun main() {
    val twoDigits = 10 until 100 // 10..99와 같음. 100은 포함 X
}

- downTo: 범위에 아래로 내려가는 방향성을 추가 (진행 타입)

fun main() {
    println(5 in 10 downTo 1) // true
    println(5 in 10..1) // false: 빈 진행
    println(5 in 1 downTo 1) // false: 빈 진행
}

- step: 진행의 간격을 지정 (반드시 양수여야 함. -방향을 원한다면 downTo함수를 통해 사용한다.)

fun main() {
    println(1..10 step 3) // 1, 4, 7, 10
    println(15 downTo 10 step 2) // 15, 13, 11, 9

    // 주석 형식처럼 출력하기 //
    val range1 = 1..10 step 3
    val range2 = 15 downTo 10 step 2

    println(range1.joinToString())
    println(range2.joinToString())
}

 

=> 범위라는 것을 언어의 수준에서 사용하여 사용자에게 더 편리하게 한다.


문자열, 배열과 범위

- 문자열.substring()에 범위 사용하기

fun main() {
    println("Hello, World".substring(1..4)) // ello
    println("Hello, World".substring(1 until 4)) // ell
    println("Hello, World".substring(1, 4)) // ell: substring(1 until 4)와 같은 동작
}

- 배열.sliceArray()에 범위 사용하기

fun main() {
    val a = IntArray(10) { it * it }.sliceArray(2..5) // 4, 9, 16, 25
    val b = IntArray(10) { it * it }.sliceArray(2 until 5) // 4, 9, 16
    // sliceArray는 범위 인덱스의 요소를 추출하여 새로운 배열을 생성 (it는 0부터 시작)

    // 주석처럼 출력 //
    println(a.joinToString())
    println(b.joinToString())
}

in / !in을 배열, 문자열 등에 사용하기

- in / !in은 배열, 문자열 등에 원소가 있는지를 파악할 때 사용 가능

fun main() {
    val numbers = intArrayOf(3, 7, 2, 1)
    val text = "Hello!"

    println(2 in numbers) // true
    println(9 !in numbers) // true
    println(4 in numbers) // false
    println('a' in text) // false
    println('H' in text) // true
    println('h' !in text) // true
}

when 구문 (≒ switch문)

- if ... else if ... else if ... 의 깔끔한 대안

fun hexDigit(n: Int): Char { // 0 ~ 15 까지의 10진수를 16진수로 변환하는 함수
    when {
        n in 0..9 -> return '0' + n
        n in 10..15 -> return 'A' + n - 10
        else -> return '?'
    }
}

- when을 식으로 사용 가능

fun hexDigit(n: Int) = when {
    n in 0..9 -> '0' + n
    n in 10..15 -> 'A' + n - 10
    else -> '?'
}

- when의 대상 특정

fun hexDigit(n: Int) = when(n) {
    in 0..9 -> '0' + n
    in 10..15 -> 'A' + n - 10
    else -> '?'
}

when 구문의 복잡한 예제

fun main() {
    val num = readLine()!!.toInt()
    println(numberDescription(num))
}

fun numberDescription(n: Int): String
= when {
    n == 0 -> "Zero"
    n == 1 || n == 2 || n == 3 -> "Small"
    n in 4..9 -> "Medium"
    n in 10..100 -> "Large"
    n !in 0..Int.MAX_VALUE -> "Negative"
    else -> "Huge"
}
fun main() {
    val num = readLine()!!.toInt()
    println(numberDescription(num))
}

fun numberDescription(n: Int): String
= when(n) {
    0 -> "Zero"
    1, 2, 3 -> "Small"
    in 4..9 -> "Medium"
    in 10..100 -> "Large"
    !in 0..Int.MAX_VALUE -> "Negative"
    else -> "Huge"
}

Kotlin에서 범위나 소속을 연산자로 제공하는 이유

- JAVA는 자바 가상 머신이 수행하는 바를 투영하는 언어로 수행 복잡도가 모두 1인 명령어로 이루어져있다.

 

- Kotlin은 사용자에게 친화적인 언어를 제공하므로서 편의성을 높이기 위해 수행 복잡도의 제한이 없는 명령어들이 존재한다.

'Study > Kotlin Study' 카테고리의 다른 글

[Kotlin] 예외 처리  (0) 2023.08.25
[Kotlin] 루프 (반복문)  (2) 2023.08.24
[Kotlin] 패키지: 패키지 개요  (2) 2023.08.22
[Kotlin] 증가 감소 연산자  (1) 2023.08.20
[Kotlin] Smart Cast  (0) 2023.08.19