변수란 무엇인가? (Variable)
1. 변수(Variable)란 무엇인가?
변수란, "변할 수 있는 수"를 뜻합니다. "變(변할 변)"과 "數(셀 수)" 한자를 사용하고 영어로는 Variable인데, 사전적으로 "어떤 관계나 범위 안에서 여러 가지 값으로 임의로 변할 수 있는 수"를 의미합니다.
여기서 "변할 수 있다"는 문장의 의미는, 프로그램 코드가 실행되는 과정에서 처리되는 값이 항상 일정한 값으로 고정되지 않고, 어떤 행위(입력, 연산 등)에 따라 그 값이 변할 수 있음을 의미합니다.
예를 들어, 사용자가 입력한 0~10 사이의 정수 세 개를 사용해, 그 값들의 총합을 구하는 프로그램을 만든다고 가정해보죠. 사용자가 입력한 값에 따라 총합이 계산되는 과정은 아래와 같을 것입니다.
입력 값 (1, 2, 3) => 총합 : 6 = 1 + 2 + 3
입력 값 (3, 0, 6) => 총합 : 9 = 3 + 0 + 6
그리고 이를 수식으로 나타내면, 다음과 같습니다.
입력 값 (A, B, C) => 총합 : X = A + B + C
위 수식에서, 사용자 입력 값 A, B, C, 그리고 계산된 총합 X 가 바로 어떤 행위에 따라 그 값이 "변할 수 있는 수", 즉, 변수(Variable)가 되는 것입니다.
그런데 한 가지 의문이 생기네요. 컴퓨터에서 어떤 연산이 실행되려면, 입력 값 A, B, C와 연산 결과인 총합 X라는 변수가 어딘가에 저장되어 있어야 할텐데요, 변수는 어디에 만들어지는 것일까요?
2. 변수와 메모리 주소. (Variable and Memory Address)
변수는 시스템의 메모리 공간 어딘가에 저장됩니다. 시스템 운영체제가 프로그램을 위해 할당한 메모리 중 어느 한 영역을 차지하고, 그 영역에 값을 저장하는 것이죠.
메모리는 프로그램 코드 관점에서 보자면 일차원적인, 선형적(Linear) 구조를 가집니다. 즉, 프로그램에 할당된 메모리 범위 내에서, "0, 1, 2, ..."와 같이, 바이트(Byte) 단위로 접근 가능하도록 만들어져 있습니다. 그리고 메모리 특정 영역의 값을 참조하기 위해 메모리 내의 위치 순서 값을 사용하는데, 이를 메모리 주소(Address)라고 부릅니다.
참고로, 이 "주소(Address)"라는 용어 때문에, 과거 땅 위치 식별을 위한 "동/번지" 주소체계에 익숙했던 사람들은, "번지"라는 단어를 사용하여 주소 값을 지칭하기도 했습니다. 예를 들자면, "12000 번지" 또는 "0x21432211 번지"처럼 말이죠.
자, 그렇다면 메모리 공간의 변수 값을 읽거나 저장하기 위해서는, 변수의 메모리 주소 값을 사용하면 되겠군요? 변수가 메모리에 저장되고, 메모리는 주소 값을 사용해 접근할 수 있으니 말이죠.
하지만 메모리 주소를 사용해 변수의 값을 참조하는 것은 거의 불가능에 가까운 일이라는 것을 쉽게 알 수 있을 것입니다. 숫자로 구성된 주소 값을 모두 외워서 코딩을 한다는 것은 말이 안되는 일이니니까요.
그래서 프로그래밍 언어에서는 메모리 주소에 만들어진 영역에 쉽게 접근할 수 있도록, 변수에 이름을 붙이고, 그 이름을 통해 메모리 주소의 값을 참조할 수 있도록 만들었습니다. 이를 변수 네이밍(Naming)이라고 합니다.
결국 변수의 이름은, 메모리 어딘가에 만들어진 영역에 접근하기 위해 프로그램 코드에서 사용할 수 있는 창구 역할을 한다고 볼 수 있습니다.
자, 여기까지, 이제 변수에 이름을 붙이고, 그 이름을 통해 메모리 주소의 값을 읽고 쓸 수 있다는 것을 알게 되었습니다.
그런데 갑자기 궁금한 점이 또 생겼습니다. 변수가 접근할 수 있는 메모리 공간의 크기는 얼마나 될까요? 무조건 딱 정해진 크기만큼만 사용할 수 있을까요? 변수마다 다르게 지정할 수 있을까요? 만약 변수마다 다르게 지정할 수 있다면, 변수가 차지하는 메모리 영역의 크기는 어디서 결정될까요? 변수 하나 당 무조건 1 바이트? 아니면 8 바이트? 아니면 통 크게 1024 바이트? 그리고 변수를 통해 읽고 쓸 수 있는 값의 범위 또는 종류는 어떻게 되는 걸까요? 0 또는 1? 256? 10,000? 아니면 9,878,627,623,187? 또, 알파벳 'A'는? "PROGRAMMING"이라는 문자열은?
3. 데이터 타입. (Data Type)
하나의 변수가 얼마만큼의 메모리 공간을 참조할 것인지는, 오로지 개발자의 선택에 달려있습니다. 변수를 만들 때 해당 변수의 종류를 나타내기 위한 "타입(Type)"을 지정해줌으로써 변수가 참조할 메모리 크기(바이트 단위)를 결정할 수 있습니다.
하지만 "타입(Type)"을 지정하는 이유가 단순히 메모리 크기를 결정하기 위한 것은 아닙니다. 변수가 가지는 값의 종류, 즉, 정수(Integer)인지, 실수(Float, 부동소수점 방식)인지, 문자(Character)인지, 또는 문자열(String)인지에 대한 정보도 포함하고 있습니다. 그리고 변수에 지정된 타입에 따라 변수의 사용 방식과 처리 과정이 달라집니다.
이렇게, 변수 값의 종류와 메모리 크기를 결정하는 요소를 "데이터 타입(Data Type)"이라고 말합니다. 흔히, "자료형"이라고 번역하여 표시하죠.
변수에 사용할 수 있는 데이터 타입은 프로그래밍 언어에 따라 종류와 사용 방식, 이름, 크기 그리고 목적 등이 조금씩 다릅니다. 하지만 아래의 데이터 타입들은 대부분의 프로그래밍 언어가 공통적으로 가지고 있는데, 이를 "기본 데이터 타입(Primitive Data Type)"이라고 일컫습니다.
- 불린(Boolean) : 오직 참(true) 또는 거짓(false)을 식별하기 위해 사용.
- 정수(Integer) : 정수(음수, 0, 양수)를 처리하기 위해 사용.
- 문자(Character) : 하나의 문자를 처리하기 위해 사용.
- 실수(Float) : 소수점(부동소수점)이 포함된 실수 값을 처리하기 위해 사용.
또한 기본 데이터 타입(Primitive Data Type)으로 분류되진 않지만, 프로그래밍 언어에서 공통적으로 제공되는 아래와 같은 타입들이 존재합니다.
- 배열(Array) : 동일한 데이터 타입 집합. N개의 데이터를 하나의 변수 이름을 통해 인덱스로 접근.
- 문자열(String) : 문자들의 집합. 문자(Character) 타입의 배열 형태이거나, 별도의 String 타입으로 처리.
그리고 앞서 소개한 타입들을 조합하거나 사용자가 원하는 요소들을 포함하여 새로운 타입(Type)을 정의할 수 있는데, 이를 사용자 정의 데이터 타입(User Defined Data Type)이라고 합니다. C언어의 구조체(struct) 또는 C++, Java와 같은 객체지향 언어에서 지원되는 클래스(class) 등이 바로 대표적인 사용자 정의 데이터 타입입니다.
- 구조체(Struct) : C언어와 같은 구조적 프로그래밍 언어의 기본 사용자 정의 데이터 타입.
- 클래스(Class) : C++, Java, Kotlin 등의 객체 지향 프로그래밍 언어의 기본 사용자 정의 데이터 타입.
4. 참조형 변수. (Reference Type Variable)
앞서, 변수의 이름을 통해 변수에 할당된 메모리 공간에 접근할 수 있다고 했는데요, 여기서 또 하나의 질문을 던져보죠. 변수에 할당된 메모리 영역은 무조건 해당 변수를 통해서만 접근해야 하는 걸까요? A라는 변수가 사용하는 메모리 영역을, B라는 변수가 접근해서 값을 참조할 수는 없을까요?
물론, 가능합니다. 동일한 메모리 영역에, 두 개 이상의 변수가 그 값을 참조하도록 만들 수 있습니다. 어떻게?
간단하죠! 하나의 변수가 다른 변수의 메모리 주소 값을 가리키도록 만들면 됩니다. 즉, 변수 A가 사용 중인 메모리 주소를 변수 B가 참조하도록 만들면 되는 것입니다. 이 때의 변수 B를 "참조형 변수(Reference Type Variable)"라고 합니다.
C언어의 포인터(Pointer) 타입 변수가 대표적인 참조형 변수의 한 종류인데, 자바, 코틀린, 스위프트 등, C언어보다 최근에 만들어진 프로그래밍 언어에서는 기본 데이터 타입(Primitive Data Type)을 제외한 모든 객체(Object)가 참조형 변수로 사용됩니다.
5. 참고.
- .
.END.