AiPE

상수(Constant)와 리터럴(Literal)의 정의와 관계 (cf. 프로그래밍에서의 상수와 수학에서의 상수) 본문

[XiBBaL] Study/Java

상수(Constant)와 리터럴(Literal)의 정의와 관계 (cf. 프로그래밍에서의 상수와 수학에서의 상수)

Oshimaker XiBBaL 2024. 3. 25. 21:27
반응형

다른 포스팅을 보고 상수와 리터럴이 대충 뭔지는 알겠으나,

 

1. 상수가 메모리의 주소라는게 무슨 말인가?

2. 그래서 프로그래밍에서 "상수"라는 것과 리터럴, 변수는 어떻게 구분하는가? 집합관계가 어떻게 되는가?

 

맥락 설명을 생략하고 결론만 빠르게 알고 싶다면

노란색으로 하이라이트 된 챕터 3. 상수와 리터럴의 명확한 정의와 구분으로 바로 넘어가도록 하자.

 

 

1. 상수(constant)란?

수학적으로 상수(constant)란 "변하지 않는 수"를 의미한다.

 

프로그래밍에서의 상수(constant)는 수학적인 정의의 상수와는 조금 다른 개념을 가진다.

 

프로그래밍에서의 상수는 "값을 저장할 수 있는 공간"의 의미를 가진다.

 

그 이유가 무엇인지를 납득하기 위해서는 "변수"의 정의를 먼저 살펴보아야 한다.

 

 

 

Q. 변수도 "값을 저장할 수 있는 공간"인데, 상수와는 뭐가 다르냐?

변수도 마찬가지로 "값을 저장할 수 있는 공간"에 해당하지만, 상수는 변수와 달리 한 번 값을 저장하면 다른 값으로 변경할 수 없다.

변수 vs 상수
상수 변수
값을 저장할 수 있는 공간
한 번 값을 저장하면 수정이 불가능함 값을 여러 번 다른 값으로 변경할 수 있음

 

즉, 프로그래밍에서 "상수"를 값을 저장할 수 있는 공간이라고 정의한 이유는 변수와 "수정가능성"에서 차이를 두고 싶었기 때문이다.

 

값을 담는 공간을 부를 때, "값을 바꿔가며 넣을 수 있는 공간 = 변수"라고 정의했기 때문에

이에 용어적인 대구를 맞추어 "값을 한번 넣으면 바꿀 수 없는 공간 = 상수"라고 용어를 쓴 것이다.

 

이렇게 정의를 해두었더니 하나의 문제가 발생했는데, 일단 문제가 발생했다는 것만 기억해두자.

이 문제가 무엇인지는 조금 뒤 알아보자.

 

 

 

Q. 아니 그러면 그냥 변수에 값을 저장하지 왜 굳이 상수 만들어서 귀찮게 하냐?

변수에도 값을 저장할 수 있지만 굳이 상수를 사용하는 경우는 주로 다음과 같은 목적을 위해서이다.

 

상수를 사용하는 이유
① 에러 방지
상수를 사용하여 잘못된 값이 할당되거나, 프로그램 실행 중 값이 변경되는 것을 방지할 수 있다. 

② 실행 시간과 메모리 등의 자원 절약
반복 등장하는 값을 상수로 고정하면 매번 연산을 진행할 필요가 없기 때문에 효율적이다.

③ 가독성 및 유지보수성 향상
코드 내에서 사용되는 일정한 값을 상수로 정의하면, 해당 값을 바꾸거나 추적할 필요가 없어 코드를 이해하고 유지보수하기 편리하다.

②는 기계 입장에서의 효율, ③은 프로그래머 입장에서의 효율이라고 할 수 있겠다.

 

 

 

Q. Java에서 변수를 선언하는 법은 알겠는데, 상수는 어떻게 선언하냐?

Java에서의 상수는 아래와 같은 문법으로 정의할 수 있다.

변수의 타입 앞에 "final" 키워드를 붙여 표현한다.

public static final int CONSTANT_1 = 100;
// 위 final은 변수가 한 번 초기화 된 후 다시 할당될수 없음을 의미한다
// final 키워드가 사용된 변수는 프로그램 실행 중 값을 다시 할당할 수 없다

 

 

 

Q. 상수는 진짜 절대 무슨일이 있어도 한 번 값을 지정하면 바꿀 수가 없냐?

일단 상수로 선언해 프로그램을 만들다가, 진짜 불가피하게 해당 상수에 다른 값을 지정해야 할 때가 있을 수도 있다.

짧고 간단한 코드라면 그냥 상수를 변수로 바꾸어주면 되겠지만,

코드가 복잡하고 길다면 일일이 바꾸어주기가 상당히 귀찮을(효율이 떨어질) 수 있다.

 

따라서, 언어에 따라 예외적으로 상수를 수정하는 방법이 존재하기도 한다. (C++의 const_cast 등)

 

예외적인 경우이며, 헷갈리니까, 바꿀 수 없다고 일단 생각하자.

 

 

 

2. 리터럴(literal)이란? 

리터럴은 "데이터 그 자체"라고 할 수 있다.

조금 더 풀어 설명하자면, 리터럴은 상수나 변수에 넣는, 변하지 않는 데이터를 의미한다.

 

변하지 않는 데이터 모두를 칭하기 때문에 class 등도 리터럴에 해당한다.

 

단, 리터럴은 "변하지 않는 값"이기 때문에 값이 계속 변한다면 리터럴이 아니며 당연히 상수에 저장할 수 없다.

 

final int Num_1 = 30;

 

간단하게, 위 예시에서 Num_1은 앞에 final이 붙었으므로 정수형 상수임을 알 수 있다.

이 때, '=' 뒤의 '30'이 바로 리터럴이다.

 

 

 

데이터에 여러가지 형식이 있듯이, 리터럴에도 여러가지 형식이 있다.

 

① 정수 리터럴(Integer Literals)

정수 값을 나타낸다. 그냥 일반적인 숫자이다.

② 부동 소수점 리터럴(Floating-point Literals)

부동 소수점 숫자 값을 나타낸다. 부동 소수점에 대해서는 아래 포스팅을 참고하자.

③ 문자 리터럴(Character Literals)

단일 문자 값을 나타낸다. 작은 따옴표(')로 묶어서 표시한다.

즉 "Hello"와 다르게, 'a'등의 한 글자 문자는 문자 리터럴에 포함된다.

④ 문자열 리터럴(String Literals)

문자들이 모여 만드는 문자열 값을 나타낸다.

큰 따옴표 (")나 백틱 (backtick, `)으로 묶어서 표시한다.


⑤ 불리언 리터럴(Boolean Literals)

참(True)이나 거짓(False)을 나타낸다.

⑥ 배열 리터럴(Array Literals)

자료들을 하나로 묶을 때 사용하는 "배열"을 초기화하는 데 사용한다.

대괄호 ([ ]) 안에 요소를 나열하여 표현한다.

 

⑦ 객체 리터럴(Object Literals)

객체를 초기화하는 데 사용한다.

중괄호 ({ }) 안에 키-값 쌍을 나열하여 표현한다.

예를 들어, {Oshimaker : XiBBaL}이라는 객체 리터럴이 있다면, Oshimaker라는 Key에 XiBBaL이라는 값이 할당되어 있는 것이다.

 

 

 

 

 

3. 상수와 리터럴의 명확한 정의와 구분

원래 12, 123, 'A'와 같은 값들을 우리는 상수라고 부르지만,

프로그래밍에서는 상수를 "값을 한 번 저장하면 변경할 수 없는 저장공간"이라는,

변수와의 "수정가능성"이라는 요소가 다른, 확장된 개념으로 사용하기 때문에

우리가 일반적으로 "상수"라고 부르는 것을 정의할 말이 따로 필요했다.

 

따라서 일반적인 의미에서의 "상수"를 정의하기 위해 리터럴(literal)이라는 용어를 도입했다.

 

따라서 둘의 집합 관계는 아래의 그림과 같다.

 

프로그래밍에서의 상수와 리터럴의 관계

 

정리하자면, 상수는 메모리의 위치 공간을, 리터럴은 그 메모리 안에 담겨있는 변하지 않는 값을 의미한다.

 

 

 

Q. 그러면 상수가 메모리의 위치라는 것이 무슨 말이냐?

컴퓨터가 상수나 변수를 저장하는 곳, 즉, 메모리의 물리적인 위치에 대한 이야기이다.

 

맨 처음 상수를 프로그래밍에서 정의할 때 "변하지 않는 데이터를 저장하는 공간"이라고 했는데, 여기에서의 공간이 메모리일 뿐이다.

 

우리가 코딩을 할 때 상수를 만들고, 그 안에 리터럴을 집어넣을 때의 상수는 추상적인 개념이지만,

여기에 그치지 않고 그 상수가 실제 하드웨어 상 어디에 있는지까지를 고려하였을 때 "상수는 메모리의 고정된 위치"라는 설명이 가능하다.

 

한 번 메모리를 할당했고, 담긴 값이 바뀌지 않으므로 메모리의 위치도 바뀌지 아니한다.

 

 

 

 

 

반응형