소년코딩

01.02 - 변수, 초기화 및 할당 (variables, initialization, and assignment)

객체(Object)

C++ 프로그램은 객체를 생성, 접근, 조작 및 파괴한다. 객체는 값을 저장하고 사용할 수 있는 메모리 조각이다. 객체는 정보를 저장하고 검색할 수 있는 메일박스 처럼 생각할 수 있다. 모든 컴퓨터에는 프로그램에서 사용할 수 있는 RAM이라는 메모리가 있다. 객체가 정의되면 해당 메모리의 조각들이 객체에 할당된다. 우리가 C ++에서 사용하는 대부분 객체는 변수의 형태로 존재한다.


변수(Variable)

x = 5;

위와 같은 명령문(statement)을 추측하면 다음과 같다. 'x에 5의 값을 할당한다.' 여기서 x는 변수다.

C++에서 변수는 단순히 이름을 가진 객체다.

이 포스트에서는 정수 변수만 고려할 것이다. 정수는 -12, -1, 0, 4 또는 27과 같은 양수(+), 음수(-) 그리고 0을 포함하여 소수점이 없는 자연수를 말한다. 정수 변수란 정수 값을 가질 수 있는 변수다.

변수를 만들기 위해서 일반적으로 정의(definition)라고 불리는 특별한 선언(declaration)을 이용한다.

아래 코드는 변수 x를 정수 변수(정수 값을 가질 수 있는 변수)로 정의하는 예제다.

int x;

위 명령문이 CPU에 의해 실행되면, RAM으로부터 메모리의 조각들이 저장된다. (이것을 인스턴스화라고 한다.)

예를 들어 변수 x에 메모리 위치 140이 지정되었다고 가정해 보자. 프로그램이 표현식(expression)이나 명령문(statement)에서 변수 x를 찾을 때마다 값을 얻기 위해 메모리 위치 140을 조사할 것이다.

변수로 수행되는 가장 일반적인 작업은 대입 연산자(=)를 이용한 할당(assignment)이다.

x = 5;

CPU가 위 명령문을 실행하면 '메모리 위치 140에 5의 값을 입력하십시오.'로 해석한다.

나중에 프로그램에서 std::cout를 사용하여 화면에 그 값을 출력할 수 있다.

std::cout << x; // x(메모리 위치 140)의 값을 콘솔에 출력한다.

L-Value 와 R-Value

일반적으로 대입 연산자(=)의 피연산자 중 왼쪽에 위치하면 l-value, 오른쪽에 위치하면 r-value라고 한다. 아주 틀린 얘기는 아니지만 다른 관점에서 바라볼 필요가 있다.

C++에서 변수는 l-value다. l-value메모리상에서 지속적인 주소(위치)를 가진 값이다. 즉, 표현식(expression) 이후에도 없어지지 않고 지속된다. 변수들은 주소를 가지고 있으므로 모두 l-value다.

할당(assignment)을 수행할 때, 대입 연산자의 왼쪽 편은 l-value이어야 한다.

5 = 6;

위와 같은 코드는 5가 l-value가 아니므로 컴파일 오류가 발생한다.

값 5에는 위치를 가진 메모리가 없으므로 아무것도 할당할 수 없다. 5는 5를 의미하며, 값은 다시 할당할 수 없다.

l-value의 반대는 r-value다. r-value는 지속적인 메모리 주소와 관련이 없는 값이다. 예를 들면 숫자(5)와 표현식(x + 2)과 같다. 5는 5로 평가되고, x + 2는 변수 x의 값 + 2로 평가된다.

r-value표현식이 종료된 이후에는 더이상 존재하지 않는 임시적인 값이다.

int y;     // y를 정수 변수로 정의한다.
y = 4;     // 4(r-value)는 4로 평가되어지고, y(l-value)에 할당된다.
y = 2 + 5; // 2(r-value) + 5(r-value)는 7(r-value)로 평가되어지고, y(l-value)에 할당된다.

int x;     // x를 정수 변수로 정의한다.
x = y;     // y(l-value)는 7로 평가되어지고, x(l-value)에 할당된다.
x = x;     // x(l-value)는 7로 평가되어지고, x(l-value)에 할당된다.
x = x + 1; // x(l-value) + 1(r-value)는 8(r-value)로 평가되어지고, x(l-value)에 할당된다.

위 코드에서 가장 헷갈리는 표현식을 살펴보자.

x = x + 1;

위 문장(statement)에서 변수 x는 두 가지 다른 상황에서 쓰이고 있다. 대입 연산자의 왼쪽 'x'는 값을 저장하는 l-value(주소가 있는 값)로 쓰이고 있다. 반면에 대입 연산자의 오른쪽 'x'는 값을 생성하기 위해 쓰인다. (여기서는 7) C++은 명령문을 평가할 때 아래와 같이 평가한다.

x = 7 + 1;

이것은 변수 x에 값 8을 할당한다는 것을 보여준다.


초기화(Initialization) vs 할당(Assignment)

변수가 정의(definition) 된 후에 대입 연산자(=)를 통해 값을 할당(assignment) 할 수 있다.

int x;     // 변수 정의
x = 5;     // 값 5를 변수 x에 할당한다. 

C++ 에서는 변수를 정의함과 동시에 같은 단계에서 초깃값을 지정할 수 있다. 이것을 초기화(initialization)라고 한다.

int x = 5; // 변수 x를 값 5와 함께 초기화한다.

변수는 정의될 때만 초기화 할 수 있다.

초기화되지 않은 변수(uninitialized variable)

일부 프로그래밍 언어와는 다르게 C++ 에서는 변수를 자동으로 어떤 기본값(default value)으로 초기화하지 않는다. 그러므로 변수가 컴파일러에 의해 메모리 위치가 할당되면, 그 변수의 기본값(default value)은 이미 그 메모리 위치에 할당되어 있는 쓰레기 값(garbage value)이 된다.

이렇게 초기화 또는 할당을 통해 알려진 값이 제공되지 않은 변수를 초기화되지 않은 변수(uninitialized variable)라고 한다.

초기화되지 않은 변수를 사용하면 아래와 같이 잘못된 결과가 발생할 수 있다.

#include <iostream>

int main()
{
    // 정수 변수 x를 정의한다.
    int x; // 초기화되지 않은 변수

    // 정수 변수 x의 값을 출력한다.
    std::cout << x; // 초기화되지 않았기 때문에 쓰레기 값을 출력한다.(프로그램이 제대로 실행된다.)

    return 0;
}

초기화되지 않은 변수를 사용하는 것은 프로그래머의 가장 일반적인 실수 중 하나이며, 프로그램이 제대로 실행될 수 있으므로 디버깅 하는 것이 어렵다.

그러나 다행히도 현대 컴파일러의 대부분은 초기화되지 않은 변수를 사용할 경우 경고를 출력한다.

warning C4700: uninitialized local variable 'x' used 

경험상 가장 좋은 방법은 변수를 초기화(initialization)하는 것이다. 이렇게 하면 변수에 항상 일관된 값이 할당되어 다른 곳에서 문제가 발생하면 디버깅 하기가 쉬어진다.


cpp 번역: 이 포스트의 원문은 http://www.learncpp.com/cpp-tutorial/13-a-first-look-at-variables-initialization-and-assignment/ 입니다.

댓글 로드 중…

블로그 정보

소년코딩 - 소년코딩

소년코딩, 자바스크립트, C++, 물리, 게임 코딩 이야기

최근에 게시된 이야기