본 게시글은 부스트코스의 코틀린 기본프로그래밍을

시청한 후 학습한 정보를 기록하는 목적의 게시글입니다.

부스트코스

 

다 함께 배우고 성장하는 부스트코스

부스트코스(boostcourse)는 모두 함께 배우고 성장하는 비영리 SW 온라인 플랫폼입니다.

www.boostcourse.org

코틀린 기본프로그래밍(1/2)

 

코틀린 프로그래밍 기본1/2(함수편)

부스트코스 무료 강의

www.boostcourse.org

본 게시글은 부스트코스 서포터즈 3기 활동 게시글입니다.


#3-1 함수를 선언하고 호출해 보기 (1)

- 들어가기 전에

프로그래밍을 하다 보면 반복 입력하는 코드가 생기기 마련입니다. 이런 경우 반복되는 부분만 따로 떼어 함수로 정의하면 코드를 재사용할 수 있어 유용합니다. 또, 함수를 잘 이용하면 프로그램을 구조적으로 만들 수도 있습니다. 현대 언어의 특징을 많이 가지고 있는 코틀린은 함수를 다양한 형태로 사용할 수 있도록 지원합니다.

먼저 함수의 선언 방법에 대해서 공부해 봅시다.

 

- 핵심 키워드

  • fun
  • 반환 자료형, Unit
  • 최상위 함수(Top-level function)
  • 지역 함수(Local function), 지역 변수(Local variable)
  • 스택(stack)과 스택 프레임

 

1) 함수의 정의

함수란 특정 기능 역할을 하는 Box를 연상해볼 수 있는데,

입력에 따라서 우리가 원하는 동작을 수행한 후 결과를 출력하거나 동작만을 수행하는 도구를 말한다.

fun sum(a: Int, b: Int): Int{
    var sum = a+b
    return sum
}

코틀린에서 함수는 ` fun ` 이라는 키워드를 통해서 선언할 수 있다.

또한 함수의 매개변수 콜론 옆 혹은 함수의 매개변수 콜론 옆에는,

각각 매개변수의 타입 혹은 반환 타입을 명시하여야 한다.

만약 함수가 자료를 반환하지 않는 경우에는 그 자료명으로 ` unit `을 사용할 수 있다.

 

2) 함수의 간략화된 표현

fun sum(a: Int, b: Int):Int = a + b

코틀린에서 함수를 위와 같이 간략화하여 표현할 수 있다.

또한, 파라미터로 넘겨주는 자료형 a, b가 모두 Int이기 때문에,

return되는 변수의 자료형 역시 추론가능하다. 이 역시 생략하여 아래와 같이 표현할 수 있다.

fun sum(a: Int, b: Int) = a + b

 

* Top-level(최상위) 함수와 지역 함수

Top-level 함수는 정의의 순서와 상관없이 그 함수의 이름을 읽을 수 있으나,

함수 내부에 선언되는 지역 함수의 경우는 함수가 사용되기 이전에 정의되어 있어야 한다.

아래의 케이스들을 살펴보자.

True

fun sum(a : Int, b : Int): Int {
    return a + b
}

fun main(){
    val result1 = sum(2, 3)
    println(result1)
}

True

fun main(){
    val result1 = sum(2, 3)
    println(result1)
}

fun sum(a : Int, b : Int): Int {
    return a + b
}

False

fun main(){
    val result1 = sum(2, 3)
    
    fun sum(a : Int, b : Int): Int {
        return a + b
    }
    
    println(result1)
}

True

fun main(){
    
    fun sum(a : Int, b : Int): Int {
        return a + b
    }
    
    val result1 = sum(2, 3)    
    println(result1)
}

 

#3-1 함수를 선언하고 호출해 보기 (2)

- 들어가기 전에

이번에는 함수 매개변수의 기본값과 이름을 사용하는 방법에 대해서 이야기 합니다. 마지막에는 함수의 호출 원리에 대해서 이야기해 볼까요?

 

- 핵심 키워드

  • fun (변수명: 자료형 = 기본값...)
  • 매개변수의 기본값
  • 이름있는 인자
  • 함수 호출의 원리
  • 스택 프레임

 

1) 판단문이 포함된 max() 함수

판단문을 활용하여 a와 b중 큰 수를 반환하는 함수 max를 구현하고자 한다.

fun max(a: Int, b: Int): Int{
    return if (a > b) a else b
}

이와 같은 형태로 함수의 return과 판단문을 결합하여 응용할 수 있다.

 

2) 반환값이 없는 unit 함수

fun outfunc(name: String): Unit{
    println("Name: $name")
}

이렇게 함수가 return값 없이 출력만을 담당하는 같은 경우는 unit을 선언하여 구현할 수 있다.

C/C++ 혹은 JAVA에서의 void와 유사한 동작을 수행한다고 이해하면 된다.

차이점으로는 Unit같은 경우는 return Unit 구문이 생략되어 있는 형태로 unit이 반환된다는 점이다.

마찬가지로 아래와 같이 함수의 자료형 역시 생략할 수 있다.

fun outfunc(name: String){
    println("Name: $name")
}

 

이때까지 우리가 선언한 함수들 역시 아래와 같이 축약된 형태로 선언할 수 있다.

fun sum(a : Int, b : Int) = a + b
fun max(a: Int, b: Int) = if (a > b) a else b
fun outfunc(name: String) = println("Name: $name")

 

3) 가변 인자

함수의 인자가 결정되지 않고, 매번 바뀌는 경우는 어떻게 구현할 수 있을까?

인자의 개수에 따라 함수를 모두 만드는 것은 매우 비효율 적일 것이다.

여기서 활용할 수 있는게 코틀린의 ` 가변 변수 ` 이다.

그것을 위한 키워드가 ` vararg `이고 vararg로 선언된 변수는 하나 이상의 인자들 받아들일 수 있다.

fun normalVarargs(vararg a : Int){
    for(num in a){
        println(num)
    }
}

위 코드 같은 경우는 인자 a는 vararg로 선언되어 여러개의 인자를 받을 수 있다.

따라서 반복문을 통해 a로 들어온 모든 인자를 출력하는 동작을 수행함으로써 vararg의 동작을 확인하고자 한다.

fun normalVarargs(vararg a : Int){
    for(num in a){
        println(num)
    }
}

fun main(){
	normalVarargs(...a: 1, 2, 3, 4)
 }
1
2
3
4

 

What happens when we call a Function

 

What happens when we call a Function - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

Stack Memory and Heap Space in Java

 

Stack Memory and Heap Space in Java | Baeldung

Explore how Stack Memory and Heap Space works and when to use them for developing better Java programs.

www.baeldung.com

함수가 호출되었을 때 Stack과 Heap의 동작을 알고 싶다면, 위 두 게시글을 참조하면 좋을 것 같다.

코틀린 역시 Stack Frame의 경우 Java 혹은 다른 언어와 유사하게 동작한다.

 

#3-2 함수를 활용한 예제 만들기

들어가기 전에

이제까지 배운 함수를 이용해 간단한 예제를 만들어 볼까요?

 

예제 : 평균 구하기

목표: 하나 이상의 실수를 받아서 모든 실수의 합의 평균을 구하고 출력 하려고 합니다.

다음 조건을 만족하는 함수를 구현해 보세요!

  • 초기값을 위한 인자는 Float형
  • 초기값은 두번째 부터 나열된 인자의 최종 평균 결과에 더함
  • 초기값에 아무런 인자를 입력하지 않으면 0을 기본 사용
  • 두번째부터 받아들일 인자는 가변형 인자로 모두 실수형 Float
  • 반환값은 모든 인자의 평균값으로 마찬가지로 실수형 Double

 

문제 : 

fun avgFunc(initial: ____(1)______, _____(2)_____ numbers: Float): Double {
    var result = 0f
    for (num in numbers) {
        ________(3)_________
    }
    println("result: $result, numbers.size: ${numbers.size}")
    val avg = __________(4)____________
    return ________(5)_________
}

fun main() {
    val result = avgFunc(5f, 100f, 90f, 80f)  // 첫번째 인자: 초기값, 이후 인자는 가변인자
    println("avg result: $result")
}

정답 :

fun avgFunc(initial: Float=0f, vararg numbers: Float): Double {
    var result = 0f
    for (num in numbers) {
        result += num
    }
    println("result: $result, numbers.size: ${numbers.size}")
    val avg = result/numbers.size
            return (avg+initial).toDouble()
}

fun main() {
    val result = avgFunc(5f, 100f, 90f, 80f)  // 첫번째 인자: 초기값, 이후 인자는 가변인자
    println("avg result: $result")
}
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기