[Android/Kotlin] 8 조건문

[Android/Kotlin] 8 조건문

조건문에 대해서 알아보자!


  • 조건문이란 특정 조건에 따라 실행을 달리하고자 할 때 사용한다.
  • ‘제어문’이라고도 하는데, 이는 코드의 흐름을 조건에 따라 바꿀 수 있기 때문이다.
  • 제어문에는 크게 조건문에 해당하는 if, when, 그리고 반복문에 해당하는 for, while이 있다.

조건문 if

  • 조건문은 어떨 때 사용할까?
    • 예로 복권 당첨 프로그램을 들 수 있다.
    • 내가 가진 복권 번호가 1, 2, 3, 4, 5, 6이고 이번 주 당첨 번호가 5, 6, 7, 8, 9, 10일 경우 당첨 여부를 조건문 중 하나인 if를 사용해서 다음과 같이 작성할 수 있다.
var myNumbers = "1, 2, 3, 4, 5, 6"
var thisWeekNumbers = "5, 6, 7, 8, 9, 10"
if (myNumbers == thisWeekNumbers){ // if문 시작(해당 조건을 만족하면 if 블록 내의 코드를 수행)
        Log.d("Lotto", "당첨되었습니다!")
} // if문 끝
  • 위 코드를 보면, 내 번호인 myNumbers와 이번 주 당첨 번호인 thisWeekNumbers가 같은지를 조건문인 if로 비교한 후 같을 경우에는 “당첨되었습니다.”를 출력한다.
  • 그러나 조건이 맞지 않을 경우 아무것도 출력하지 않는다.
  • 이렇게 특정 코드를 실행하거나 실행하지 않을 때에 조건문을 사용할 수 있다.
  • 조건문이란?
    • 주어진 조건식의 결괏값이 참인지 거짓인지에 따라 코드를 실행할 것인지 혹은 다른 코드를 실행할 것인지 판단하기 위한 프로그래밍 문법이다.
    • Kotlin에서는 ifwhen, 두 가지 형태의 조건문을 사용할 수 있다.

if 문을 사용하기 위한 조건

  • if 문의 조건식에는 비교 연산자(==, <, >)와 논리 연산자(&&, )를 사용한 조건식만 사용 가능하며, 조건식의 결과는 Boolean 타입인 ture(참)와 false(거짓)로 나타낸다.
  • 비교 연산자(==, <, >)는 보통 두 값을 비교하는 연산자로 다음과 같은 종류가 있다.
연산자의미사용 예결과
>왼쪽이 크면 true, 작으면 false 반환1 > 2false
<왼쪽이 작으면 true, 크면 false 반환1 < 2true
>=왼쪽이 크거나 같으면 true, 아니면 false1 >= 2false
<=왼쪽이 작거나 같으면 true, 아니면 false2 <= 2true
==2개 항의 값이 같으면 true, 아니면 false1 == 2false
!=2개 항의 값이 다르면 true, 아니면 false1 != 2true
  • 비교 연산자는 다음 예제처럼 비교의 결괏값이 true 또는 false 중의 하나인 Boolean 타입으로 반환된다.
var a = 30
var b = 19
var bigger = a > b
Log.d("비교 연산자", "a는 b보다 큽니다.: $bigger") // a는 b보다 큽니다.: true
  • 논리 연산자는 주로 비교 연산자로 나타난 결과를 한 번 더 연산하기 위해서 사용된다.
연산자의미사용 예결과
&&논리곱. 두 항이 모두 true일 때에는 true, 아니면 false(2 > 1) && (3 < 1)false
||논리합. 두 항 중 하나의 항이 true일 때에는 true, 아니면 false(2 > 1) || (3 < 1)true
!부정 단항 연산자. true를 false로, false를 true로 바꿈! (2 > 1)false
  • 논리 연산자의 결괏값도 다음처럼 Boolean 타입으로, true 또는 false 이다.
var a = 30
var b = 19
var c = 37
var bigger = a > b && a > c
Log.d("비교 연산자", "a는 b보다 크고, c보다도 큽니다:$bigger") // a는 b보다 크고, c보다도 큽니다.: false

기본적인 if 문 사용하기

  • 예제를 통해 if 문의 다양한 형식을 살펴보겠다.

  • 다음은 기본적인 if 문의 사용 예이다.

if (조건식) {
    // 조건식이 참일 경우 실행되는 코드 영역
}
  • if 다음에 소괄호 ( )를 작성하고, 소괄호 안에 조건식을 작성한다.

  • 조건식의 결과가 true일 때 처리할 코드를 코드 블록 { } 안에 작성한다.

  • 코드 중간의 여는 중괄호 { 로 시작해 닫는 중괄호 } 를 만날 때까지를 코드 블록(Code Block) 또는 코드 스코프(Code Scope)라고 한다.

  • 다음 예제 코드의 결과를 예측해보자.

var out = 0
var strike = 3
if (strike > 2) {
    out = out + 1
}
  • if 문의 조건식에는 strike가 2보다 크므로 out에 1을 더해준다.

  • Log를 사용해서 변수 out을 출력하면 ‘1’이 출력된다.

if ~ else 문 사용하기

  • 이번에는 if와 else를 같이 사용한 예이다.

  • 조건식의 결과가 참이면 if 다음에 있는 코드 블록 { } 의 코드가 실행되고, 거짓이면 else 다음에 있는 코드 블록 { } 의 코드가 실행된다.

if (조건식) {
    // 조건식이 참일 경우 실행되는 코드 영역
} else {
    // 조건식이 거짓일 경우 실행되는 코드 영역
}
  • 이번에는 안드로이드 스튜디오에서 직접 코드를 작성해서 Log를 확인해보도록 하겠다.
package net.flow9.thisiskotlin.basicsyntax

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var ball = 4
        if (ball > 3) { // ball이 3보다 크면 여기 블록의 코드가 실행됩니다.
            Log.d("ControlFlow", "4볼로 출루합니다.")
        } else { // 그렇지 않으면 else 다음에 있는 블록의 코드가 실행됩니다.
            Log.d("ControlFlow", "타석에서 다음 타구를 기다립니다.")
        }
    }
}
  • 위 코드를 실행하면 로그캣(Logcat)에는 “4볼로 출루합니다.”라는 문구를 확인할 수 있다.

여기서 잠깐!

  • 주석이란?

    • 개발자가 코딩과 관련한 메모를 코드상에 남길 수 있는 것을 주석이라고 한다.

    • 위 코드에서 if 문이 있는 줄의 중간에 //를 사용해서 뒤에 나오는 문장을 주석 처리하였다.

    • 주석 처리된 문장은 컴퓨터가 해석하지 않는다.

    • 주석은 다음과 같이 세 가지로 사용된다.

      1) // 한 줄 : 한 줄을 주석 처리할 때 사용하며, 줄의 어느 위치에서 사용해도 해당 줄의 끝까지 주석 처리된다. 2) /* 여러 줄 / : 여러 줄에 걸쳐서 주석 처리할 때 사용하며, /로 시작해서 다음에 나타나는 */를 만날 때까지 모든 글을 주석 처리해서 컴퓨터가 해석하지 않는다. 3) /** 문서화 */ : 자동화 툴을 사용해서 문서화할 정보를 작성할 때는 / 다음에 **가 2개 이다.

  • 주석 사용도 중요하지만, 요즘 추세는 클래스, 함수, 변수의 이름을 점점 더 구체적으로 작성하고 있다.

    • 예를 들어 나이를 저장하는 변수를 a라고 작성하고 주석 처리하기보다는 변수명 자체를 age로 작성해서 명시적으로 기술하는 것이 좋다.
// [나쁜 예]
var a = 19 // a: 나이

// [좋은 예]
var age = 19
  • 변수명 뿐만 아니라 함수명, 클래스명 또한 이름만으로 이 함수가 무엇을 하는 함수인지, 이 클래스가 무엇을 위한 클래스인지를 유추할 수 있도록 이름을 구체적으로 기술하는 것이 중요하다!

  • 다음은 로또 번호를 만들어주는 클래스와 함수명을 작성하는 예제이다.

class Lotto {
    fun generateNumbers(){
        /* 실행 코드 */
    }
}

if ~ else if ~ else 문 사용하기

  • 다음 구문은 if 문을 반복해서 사용하는 if 문의 예시이다.
if (조건식1) {
    // 조건식1의 결과가 참일 경우 실행되는 코드 영역
} else if (조건식 2){
    // 조건식1의 결과가 거짓이고, 조건식2의 결과가 참일 경우 실행되는 코드 영역
} else {
    // 조건식1과 조건식2의 결과가 모두 거짓일 경우 실행되는 코드 영역
}
  • 이번에는 동일한 조건에서 2개의 if 문으로 작성했을 때와 else if 문을 사용했을 때를 비교해보겠다.

  • 안드로이드 스튜디오에 다음과 같이 코드를 작성한다.

package net.flow9.thisiskotlin.basicsyntax

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var a = 1
        var b = 2
        var c = 3

        // 1. if 문 두 번 사용하기
        if (a < b) {
            Log.d("ControlFlow", "1: a는 b보다 작습니다.")
        }
        if (a < c) {
            Log.d("ControlFlow", "1: a는 c보다 작습니다.")
        }

        // 2. else if 문 사용하기
        if (a < b) {
            Log.d("ControlFlow", "2: a는 b보다 작습니다.")
        } else if (a < c) {
            Log.d("ControlFlow", "2: a는 c보다 작습니다.")
        }
    }
}

/** [로그캣 출력 내용]
1: a는 b보다 작습니다.
1: a는 c보다 작습니다.
2: a는 b보다 작습니다.
 */
  • if 문만 2개 사용할 경우 2개의 if 문이 모두 실행되지만, else if 문을 사용하면 앞의 if 문 조건식을 만족하면 다음에 나오는 else if 문은 실행되지 않는다.

변수에 직접 if 문 사용하기

  • if 문의 조건식 결과를 변수에 대입할 수 있다.

  • 다음 예제는 a와 b를 비교했을 때 a가 b보다 더 크므로 변수 bigger에 ‘5’를 대입한다.

var a = 5
var b = 3
var bigger = if (a > b) a else b

if 문의 마지막 값을 반환값으로 사용하기

  • 위의 코드와 같은데 if 문의 코드 영역이 여러 줄일 경우에도 마지막 줄을 변숫값으로 사용할 수 있다.
var a = 5
var b = 3
var bigger = if (a > b){
    var c = 30
    a // 마지막 줄의 a 값이 변수 bigger에 저장됩니다.
} else {
    b
}
  • 안드로이드 스튜디오에서 다음과 같이 코드를 작성해보자!
package net.flow9.thisiskotlin.basicsyntax

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var eraOfRyu = 2.32
        var eraOfDegrom = 2.43

        val era = if (eraOfRyu < eraOfDegrom) {
            Log.d("MLB_Result", "2019 류현진이 디그롬을 이겼습니다.")
            eraOfRyu
        } else {
            Log.d("MLB_Result", "2019 디그롬이 류현진을 이겼습니다.")
            eraOfDegrom
        }

        Log.d("MLB_Result", "2019 MLB에서 가장 높은 ERA는 ${era}입니다.")
    }
}
/** [로그캣 출력 내용]
2019 류현진이 디그롬을 이겼습니다.
2019 MLB에서 가장 높은 ERA는 2.32입니다.
 */

여기서 잠깐!

  • 문자열 템플릿: 문자열 안에서 수식 사용하기

    • 위 소스 코드의 마지막 줄을 보면 템플릿에 ${ } (달러와 중괄호)를 사용한 것을 확인할 수 있다.

    • 변수가 하나인 경우에는 $변수의 형태로 사용할 수 있지만, 추가적인 연산식이 필요한 경우에는 ${코드 블록} 안에 수식을 입력하는 형태로 사용할 수 있다.

"문자열 $변수 문자열"
"문자열 ${변수 + 1} 문자열"

// 가독성을 높이기 위해 변수 하나만 있을 때도 { }를 사용할 수 있습니다.
"문자열 ${변수} 문자열"

조건문 when

  • 조건문 when을 이해하기 위해서는 먼저 다른 언어의 switch 문을 공부하는 것이 도움이 된다.

  • switch 문은 if 문의 연산식에서 사용되는 비교 연산자 중에 ==만 사용해서 같은 값인지를 비교하는 조건문이다.

  • Kotlin을 제외한 거의 모든 컴퓨터 언어에서는 switch라는 이름으로 사용되며 선택문이라고 불리기도 한다.

switch (변수){
    case 비교값:
    // 변숫값이 비교값과 같다면 이 영역이 실행됩니다.
}
  • Kotlin의 when 문은 다른 언어와는 다르게 같은 값뿐만 아니라 범위 값도 처리할 수 있고 사용 방법도 더 많다.

  • Kotlin에서의 when 문은 특정 값을 선택할 수 있는 switch의 사용법에 if 문의 범위 비교 기능이 더해진 if 문의 확장판이라고 생각하면 될 것 같다.

일반적인 형태의 when 사용하기

  • when 다음에 괄호 ( )를 작성하고 괄호 안에는 주로 비교 대상 파라미터로 사용할 변수명을 입력한다.

  • if에서처럼 괄호 다음에 중괄호 { }를 사용해서 when 블록을 구분하고 블록 내부에서 비교할 값은 화살표 연산자(Arrow Operator ‘->’)를 사용해서 선택한다.

when (파라미터) {
    비교값 -> {
        // 변숫값이 비교값과 같다면 이 영역이 실행됩니다.
    }
}
  • 위에서 살펴본 switch 문과 비교하면 값을 비교하는 줄 앞의 case가 없어지고 비교값 다음의 콜론이 화살표 연산자(->)로 대체되었다.

  • 여러 개의 값을 하나의 when 문에서 비교할 수도 있다.

when (파라미터) {
    비교값1 -> {
        // 변숫값이 비교값1과 같다면 이 영역이 실행됩니다.
    }
    비교값2 -> {
        // 변숫값이 비교값2와 같다면 이 영역이 실행됩니다.
    }
    else -> {
        // 변숫값이 앞에서 비교한 것들과 다르면 이 영역이 실행됩니다.
    }
}
  • 안드로이드 스튜디오에서 아래 코드를 실행하고 로그캣에 출력되는 로그를 확인해보자!
package net.flow9.thisiskotlin.basicsyntax

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var now = 10
        when (now) {
            8 -> {
                Log.d("when", "현재 시간은 8시 입니다.")
            }

            9 -> {
                Log.d("when", "현재 시간은 9시 입니다.")
            }

            else -> { // 위의 모든 조건에 맞지 않으면 else 다음 코드가 실행 됩니다.
                Log.d("when", "현재 시간은 9시가 아닙니다.")
            }
        }
    }
}

/** [로그캣 출력 내용]
현재 시간은 9시가 아닙니다.
 */

콤마로 구분해서 사용하기

  • 특정 값을 비교하는데 결과 처리가 동일하다면 콤마(,)로 구분해서 한 번에 비교할 수 있다.
package net.flow9.thisiskotlin.basicsyntax

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var now = 9
        when (now) {
            8, 9 -> {
                Log.d("when", "현재 시간은 8시 또는 9시 입니다.")
            }
            else -> { // 위의 모든 조건에 맞지 않으면 else 다음 코드가 실행 됩니다.
                Log.d("when", "현재 시간은 9시가 아닙니다.")
            }
        }
    }
}

/** [로그캣 출력 내용]
현재 시간은 8시 또는 9시 입니다.
 */

범위 값을 비교하기

  • in을 사용해서 범위 값을 비교할 수도 있다.

  • if 문의 비교 연산자 중 <=, >= 과 같은 기능을 구현할 수 있다.

package net.flow9.thisiskotlin.basicsyntax

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var ageOfMichael = 19
        when (ageOfMichael) {
            in 10..19 -> {
                Log.d("when", "마이클은 10대 입니다.")
            }

            !in 10..19 -> {
                Log.d("when", "마이클은 10대가 아닙니다.")
            }

            else -> {
                Log.d("when", "마이클의 나이를 알 수 없습니다.")
            }
        }
    }
}

/** [로그캣 출력 내용]
마이클은 10대 입니다.
 */

파라미터 없는 when 사용하기

  • when 다음에 오는 괄호를 생략하고 마치 if 문처럼 사용할 수도 있다.
package net.flow9.thisiskotlin.basicsyntax

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var currentTime = 6
        when {
            currentTime == 5 -> {
                Log.d("when", "현재 시간은 5시 입니다.")
            }

            currentTime > 5 -> {
                Log.d("when", "현재 시간은 시가 넘었습니다.")
            }

            else -> {
                Log.d("when", "현재 시간은 5시 이전입니다.")
            }
        }
    }
}

/** [로그캣 출력 내용]
현재 시간은 5시가 넘었습니다.
 */

if 문과 when 문은 언제 사용할까?

  • “조건문이 2개나 있는데 어떤 것을, 언제 사용할지 모르겠다면?”

  • 구분 방법을 살펴보겠다.

  • 일상적으로 사용하는 데이터 중에서 시간과 관련된 데이터가 있는데 시간 데이터에는 년, 월, 일, 요일, 시간 등의 많은 종류의 데이터가 있다.

  • 이 데이터 중에서 연도 데이터와 요일 데이터를 비교하면 다음과 같은 구체적인 특징이 있다.

    • 연도 데이터

      • … 2019, 2020, 2021, 2022, 2023 … : 범위를 한정할 수 없고 개수가 많다.
    • 요일 데이터

      • 월, 화, 수, 목, 금, 토, 일: 값을 특정할 수 있고 개수가 7개로 한정되어 있다.
  • 연도 데이터는 2021년과 같이 해당 값을 특정할 수 있지만, 범위가 넓고 미래의 어떤 연도까지 사용한다면 범위 자체를 한정할 수 없다.

    • 범위가 넓고 값을 특정할 수 없을 경우에는 if 문을 사용해서 처리하는 것이 바람직하다.
  • 반면, 요일 데이터는 7개로 범위가 제한되고 값도 특정할 수 있다.

    • 이럴 경우는 when 문을 사용해주는 것이 더 좋다.
when (요일) {
     -> 영어 공부를 합니다.
     -> 자전거 모임이 있습니다.
     -> 친구를 만납니다.
     -> 피아노를 칩니다.
     -> 코딩 공부로 밤을 세웁니다.
     -> 빨래를 합니다.
    else ->  청소를 합니다.
}
  • 위 코드와 같이 값을 특정할 수 있고, 개수가 많지 않은 경우에는 when 문을 사용하면 쉽게 잘 읽히는 코드를 작성할 수 있다.

  • 위 코드를 if 문으로 작성하면 아래와 같다.

if (요일 == ) {
    영어 공부를 합니다.
} else if (요일 == ){
    자전거 모임이 있습니다.
} else if (요일 == ){
    친구를 만납니다.
} else if (요일 == ){
    피아노를 칩니다.
} else if (요일 == ){
    코딩 공부로 밤을 세웁니다.
} else if (요일 == ){
    빨래를 합니다.
} else {
     청소를 합니다.
}
  • 위 코드는 너무 많은 else if 문으로 인해 가독성이 떨어진다는 것을 알았을 것이다!

  • 이처럼 사용하려는 값을 특정할 수 있고 값의 범위가 넓지 않다면 when 문을 사용하는 것이 더 좋은 방법일 수 있다!


© 2023. All rights reserved.

by SoftyChoo