[Kotlin] 변수

[Kotlin] 변수

프로그래밍의 가장 기초 내용이므로 꼭 이해해야 합니다!


1) 변수 var

  • 변수(Variable)란?

    • 값을 임시로 메모리(저장 공간)에 저장하고 그 저장 공간에 이름을 부여한 것을 말한다.

    • 이름과 값으로 구성되며 메모리의 특정 위치에 이름표를 붙이고 값을 담아두는 것과 같다.

    • 메모리에 값을 입력하면서 이름표를 붙여두면 소스 코드에서 해당 값을 사용하고자 할 때 앞에서 붙였던 이름으로 사용할 수 있다.

img

2) 변수 선언방식

  • 첫째, 변수 선언과 동시에 값 넣기

    • 입력되는 값으로 타입을 추론할 수 있다.

    • 값이 입력되는 순간 해당 값의 형태(문자, 숫자, 불리언 등)로 변수의 타입이 결정된다.

var 변수명(이름) = 

(예시)
var myName = "홍길동" // 변수명 myName에 문자열 "홍길동"을 입력
  • 둘째, 값으로 초기화하지 않고 선언만 하고 사용하기

    • 선언만 할 경우, 반드시 변수명 옆에 콜론(:) 구분자를 붙여서 타입(자료형)을 지정해야 한다.
var 변수명: 타입
변수명 = 

(예시)
var myAge: Int // 변수명 myAge를 Int 타입으로 선언
myAge = 27     // 숫자 '27'을 입력
  • 위 두가지 예시로 변수는 최초 선언 시에 타입이 결정된다는 것을 예상할 수 있다.

  • 변수는 한번 타입을 결정하면 동일한 타입의 값만 담을 수 있다.

  • 만약 아래와 같이 Int 타입의 변수에 문자열 “홍길동”을 입력한다면 컴파일 에러가 발생한다.

var myAge: Int
myAge = 27

myAge = "홍길동" // (X) 선언했던 값의 타입과 다르기 때문에 입력할 수 없습니다.
myAge = 19     // (O) 선언했던 타입과 같은 숫자(Int)는 입력할 수 있습니다.

3) 데이터 타입

코틀린에서 제공되는 기본 데이터 타입은 다음과 같다.

구분테이터타입설명값의 범위 및 예
숫자형Double64비트 실수-1.7E+308의 근삿값 ~ 1.7E+308의 근삿값
 Float32비트 실수-3.4E+38의 근삿값 ~ 3.4E+38의 근삿값
 Long64비트 실수-2E63 ~ 2E63-1
 Int32비트 실수-2,147,483,648 ~ 2,147,483,647
 Short16비트 실수-32,768 ~ 32,767
 Byte8비트 실수-128 ~ 127
문자형Char1 개의 문자‘글’ (외따옴표)
 String여러 개의 문자“여러 개의 글자입니다.” (쌍따옴표)
불리언형Booleantrue, false 두 가지 값true 또는 false

기본 타입

  • 기본 타입(Primitive Type)이란?

    • 변수에 저장되는 값의 크기가 미리 정해져 있는 타입을 말한다.

    • Int는 2,147,483,647까지만 저장할 수 있다.

    • Byte는 127까지만 저장할 수 있다.

    • Byte에 저장 범위를 넘어서는 128을 입력할 경우 전혀 다른 숫자가 된다.

  • String의 경우는 쌍따옴표(“ “) 사이에 몇 글자가 들어가도 상관없기 때문에 값의 크기를 특정할 수 없다. 따라서 String은 기본 타입이 아니다!

Double

  • 소수점이 있는 값을 저장할 때 사용한다.
var doubleValue: Double
doubleValue = 3.141592

Float

  • Double과 동일한 용도이지만 더 작은 범위의 숫자를 저장할 때 사용한다.

  • 안드로이드 스튜디오는 Double과 Float을 구분하기 위해 Float의 경우 숫자 끝에 ‘F’를 붙여준다.

var floatValue: Float
floatValue = 3.141592F

Int

  • 소수점이 없는 정숫값을 저장할 때 사용한다.
var intValue: Int
intValue = 2147483647
  • 다음과 같이 가독성을 높이기 위해서 언더바(_)로 자릿수를 구분할 수 있다.
var intValue: Int
intValue = 2_147_483_647
  • 다만, 언더바는 개발자가 읽기 쉽게 하기 위한 것으로 컴퓨터는 앞의 값과 동일하게 인식한다!

Long

  • Int보다 큰 범위의 정수를 저장할 수 있다.

  • Double과 Float의 관계처럼 Int와 구분하기 위해서 숫자의 끝에 ‘L’을 붙여준다.

  • Long 타입의 경우에는 설정한 글꼴에 따라 숫자 1과 구분이 어려울 수 있기 때문에 대문자를 사용한다.

var longValue: Long
longValue = 2147483647L

여기서 잠깐!

  • 정수형 변수에 실수형 값을 입력할 수 있나요?

    • 같은 숫자라도 타입이 다르면 기본적으로 입력할 수 없다.

    • 예를 들어 정수형(Int) 숫자 1과 실수형(Double) 숫자 1.0은 서로 다른 타입으로 인식하기 때문에 정수형으로 선언된 변수에 실수형 값을 입력할 수 없다.

    • 꼭 필요한 경우에는 데이터 타입(자료형)을 변환하는 과정을 거쳐서 입력할 수 있다.

Short와 Byte

  • 정숫값을 저장할 때 사용하는데 입력할 수 있는 값의 크기가 Int보다 작다.
var shortValue: Short = 32_767
var byteValue: Byte = 127

여기서 잠깐!

  • 타입을 지정하지 않은 숫자는 어떻게 저장되나요?

    • 위 예제들을 살펴보면, 정수형 변수 다음에 항상 콜론(:) 구분자를 사용해서 타입을 지정하였다.

    • 이유는 타입을 지정하지 않은 일반 숫자 값을 모두 Int 타입으로 인식해 의도치 못한 결과를 가져올 수 있기 때문이다.

var byteValue: Byte = 127 // 127이 Byte 타입으로 저장됩니다.
var byteValue2 = 127      // 127이 Int 타입으로 저장됩니다.

var floatValue: Float = 3.14F // 3.14가 Float 타입으로 저장됩니다.
var doubleValue = 3.14        // 끝에 F를 붙이지 않으면 Double로 저장됩니다.

Char

  • 하나의 글자만 외따옴표(‘‘)로 감싸서 저장할 수 있다.

  • 타입을 특정하지 않아도 외따옴표 안에 하나의 글자만 지정하기 때문에 Char로 저장된다.

var charValue = 'A'

String

  • 여러 개의 문자를 지정할 수 있다.

  • 기본 타입에는 포함되지 않지만 거의 모든 컴퓨터 언어에서 가장 많이 사용되는 타입이다.

var stringValue: String = "ABCDEF"

Boolean

  • true, false 둘 중에 1개의 값을 저장할 수 있다.

  • 주로 조건문에서 의사결정을 하기 위한 용도로 많이 사용된다.

var boolValue = true

여기서 잠깐!

  • Int 2,147,483,647 값에 1을 더하면?

    • 양수의 저장

      • Int는 32비트까지 표현할 수 있기 때문에 32개의 비트로 구성되어 있다.

      • Int 2,147,483,647을 2진수로 변환하면 32개의 비트로 다음과 같이 표현된다.

      • 예) 0111 1111 1111 1111 1111 1111 1111 1111 <- 가장 앞의 비트 0은 값이 아닌 부호 비트로, 부호 비트가 0이면 양수(+), 1이면 음수(-) 이다.

    • 2의 보수와 입력값의 제한

  • 대부분의 컴퓨터는 음수를 ‘2의 보수법’으로 계산하여 저장한다.

  • 이는 음수의 절댓값을 2진수로 바꾸고(1의 보수), 여기에 다시 1을 더하는(2의 보수) 것을 말한다.

  • -2,147,483,648은 값(1의 보수)에 1을 더한 결과이므로 가장 오른쪽의 1부터 자리가 바뀌면서 모두 0으로 바뀌게 된다.

  • Int 타입에 저장할 수 있는 가장 큰 값인 2,147,483,647을 이진수로 표시하면 다음과 같다.

  • 예) 0111 1111 1111 1111 1111 1111 1111 1111

  • 위 값에 1을 더하면 모든 값이 올림이 되면서 음수 -2,147,483,648이 되고 의도치 않은 결과가 발생할 수 있다. –> 1000 0000 0000 0000 0000 0000 0000 0000

  • Byte나 Long도 동일한 원리로 동작합니다.

  • 데이터 타입을 선언할 때는 저장될 데이터의 크기를 항상 고려해주어야 한다!

실습

  • 앞서 생성한 BasicSyntax 프로젝트의 MainActivity.kt 파일에 아래와 같이 코드를 작성한다.
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 myName = "홍길동"
        var myAge: Int
        myAge = 27
        myAge = myAge + 1
        Log.d("BasicSyntax", "myName = $myName, myAge = $myAge")
    }
}

img

myName = 홍길동, myAge = 28

여기서 잠깐!

  • 문자열 템플릿

    • 코틀린에서는 더하기(+) 연산으로 2개의 문자를 하나로 합칠 수 있다.

    • 예) “홍” + “길동”처럼 2개의 문자열을 더하면 “홍길동”과 같이 하나의 문자열로 만들어 준다.

    • 추가로 문자열을 보다 쉽게 다룰 수 있는 문자열 템플릿도 제공한다.

      • 문자열 내부에서 달러($) 기호를 넣으면 해당 영역이 문자가 아닌 코드라는 것을 알려준다.
var name="홍길동"
Log.d("BasicSyntax", "제 이름은 $name 입니다.") // 출력: 제 이름은 홍길동 입니다.
  • 주의할점

    • $변수 다음에 이어지는 문자가 있다면 공백으로 구분되어야 한다.

“제 이름은 $name(공백) 입니다.” // 이어지는 문자열과의 사이에 공백이 없으면 문자열로 인식한다.

  • 실제로 편집기 창에서 Log.d 코드를 입력하면 다음과 같이 ‘tag’와 ‘msg’가 자동으로 입력된다.
Log.d(tag: "BasicSyntax", msg: "myName = $myName, myAge = $myAge")

읽기 전용 변수 Val

  • 변수의 다른 선언 방법으로는 읽기 전용 변수인 val이 있다.

  • 위의 var과는 다르게 한 번 입력된 값은 변경할 수 없다.

  • 변하지 않는 값을 미리 입력해둘 때 사용한다.

  • 상수라고도 부르기도 하지만 상수와는 의미가 조금 다르다.

읽기 전용 변수 val 선언하기

  • 선언하는 방법은 변수와 동일하며 이름 앞에 val을 붙이면 읽기 전용 변수가 된다.
val 변수명(이름) = 
  • 변하지 않는 값을 미리 지정해두고 필요에 따라 다른 값과 조합해서 사용할 수 있다.
val roadName = "필문대로"        // 미리 지정    
var address = roadName + "8길"   // 필요할 때 조합해서 사용합니다.
  • val로 정의된 변수는 값을 변경할 수 없으므로 다음과 같이 입력하면 에러가 발생한다.
val language = "kotlin"
language = "java"    // ERROR, val은 값을 변경할 수 없습니다.

상수 const

  • 상수는 주로 기준이 되는 변하지 않는 값을 입력해둘 때 사용한다.

  • 읽기 전용 변수인 val 앞에 const 키워드를 붙여서 만든다.

const val PI = 3.141592
  • val과 같이 읽기 전용인 것은 동일하지만, 컴파일 시에 값이 결정되기 때문에 Int, Long과 같은 기본형과 문자열인 String만 입력할 수 있다.

코딩 컨벤션

  • 규모가 큰 프로젝트의 경우 천 명 이상의 프로그래머가 함께 일하기도 한다.

  • 이렇게 많은 프로그래머가 각자의 방식으로 코딩하면 개발이 완료된 다음 오류를 수정하거나 업데이트를 할 때 코드를 분석하기 어려울 수 있다.

  • 대부분의 회사에서는 최초 개발자와 유지보수 담당자가 다르기에 각 프로젝트별로 코드를 작성하는 규칙을 만든다.

  • 이를 코딩 컨벤션(Coding Convention)이라고 한다.

클래스명

  • 클래스란 코드를 알아보기 쉽게 하나의 파일에 모아 놓은 것으로 생각하면 된다.

  • 대체로 클래스의 네이밍 컨벤션(명명 규칙)은 캐멀 케이스(Camel Case)를 사용한다.

  • 클래스명은 단어의 첫 글자는 대문자로, 나머지 글자는 소문자로 표기한다.

  • 새로운 단어가 나타나면 첫 글자를 대문자로 표기한다. (마치 낙타의 등처럼 높낮이가 생긴다고 해서 캐멀 케이스(낙타표기법)라고 부른다.)

  • 클래스명은 일반적으로 파일명과 동일하지만 항상 그런 것은 아니다.

  • 앞에서 작성한 코드 중에 class MainActivity…로 시작하는 코드가 있는데, 여기서 MainActivity가 클래스명이다.

    • class MainActivity <- MainActivity에서 첫 글자인 M은 대문자, 새로운 단어인 Activity의 첫 글자도 대문자이다.
  • 클래스는 다음과 같이 변수와 함수를 포함한다.

class MainActivity{
    val name = "kotlin"
    var age = 17
    fun getFullName(): String{
        ...
    }
}

함수명과 변수명

  • 캐멀 케이스를 따르며 첫 글자만 소문자로, 이후 새로운 단어의 첫 글자는 대문자로 표기한다.
// 첫 글자인 o는 소문자, 새로운 단어(Create, Activity)의 첫 글자(C, A)는 대문자
fun onCreateActivity() 
// 첫 글자인 i는 소문자, 새로운 단어(Value)의 첫 글자(V)는 대문자
var intValue: Int

상수명

  • 상수명은 모두 대문자로 작성한다.
const val HELLO: String = "안녕"
  • 상수명이 2개의 단어로 이루어져 있다면 다음 예시 코드의 상수명처럼 단어 사이를 언더바(_)로 구분하는 스네이크 케이스(Snake Case)를 사용할 수 있다.
const val HOW_ARE_YOU: String = "어떻게 지내?"

여기서 잠깐!

  • 요즘의 함수명과 변수명 작성 규칙은?

    • 요즘은 클래스명을 제외한 함수명과 변수명을 스네이크 케이스로 작성하는 회사도 많아졌다.

    • 캐멀 케이스보다 가독성이 좋기 때문이다.

    • 다만! 스네이크 케이스의 경우 상수명만 대문자를 사용하고 다른 때는 소문자를 사용한다.

fun on_create_activity()
  • 개인 선호도에 따라 캐멀 케이스, 스네이크 케이스 중 한 가지를 선택할 수 있지만, 하나의 프로젝트를 스네이크 케이스로 시작했다면 모든 코드를 스네이크 케이스로 작성하는 일관성이 있어야 한다!

들여쓰기

  • 새로운 코드 블록이 시작되면 스페이스바(Spacebar) 또는 탭(Tab) 키로 동일한 간격만큼 들여쓰기를 한다.

  • 코딩 규칙을 통틀어서 가장 중요한 규칙이다!

  • 코드에 들여쓰기(Indent)가 되어 있지 않다면 프로그래머로서 면접을 볼 기회조차 없을 수 있을 정도로 프로그래머들은 중요하게 생각한다.

class MainActivity{ // 새로운 블록의 시작
    var newVariable = 50 // 일반적으로 맨 앞에 공백 4칸 들여쓰기 사용
    
    fun on_create_activity(){ // 다시 새로운 블록의 시작
        var variable = 10 // 추가 공백 4칸(8칸) 들여쓰기
        Log.d("BasicSyntax", "변수의 값은 $variable 입니다.") // 추가 공백 4칸(8칸) 들여쓰기
    } // 공백 4칸 들여쓰기
}

© 2023. All rights reserved.

AgileCatch