강좌 첫화면으로 최근 글 보기(Post)
갈래별로 보기 categories




  3.4. 변수와 기억장소



3.4. 변수와 기억장소


변수는 프로그램을 짤 때 가장 많이 사용하는 개념입니다. 거의 모든 자료를 변수를 통해서 처리하기 때문입니다. 그래서 변수의 자료형도 다양하지만 변수의 활용범위에 따라서 또 다시 여러 종류로 나눕니다. 변수를 기억장소 종류에 따라서 나누면 자동변수, 정적변수, 외부변수, 레지스터 변수 등으로 나눌 수 있는데 이들 변수의 종류에 따라서 함수의 활용법도 달라집니다. 프로그램을 잘 짜는 사람은 이들 변수가 어디에서 어떤 모습으로 저장되었다가 변화하는지 그 과정을 잘 파악하고 있는 사람입니다. 자료형을 배웠으니 이제 변수의 기본적인 내용에 대해서 알아보도록 하겠습니다.

3.4.1. 변수의 선언과 정의


변수는 사용하기 전에 이름과 자료형을 선언해주어야 합니다.

변수는 사용하기 전에 이름과 자료형을 선언(declaration)해주어야 합니다. 선언을 통해서 어떤 변수를 어떤 자료형으로 사용할 것이라고 미리 컴파일러에게 알려주어야만 나중에 컴파일러가 에러를 내지 않고 컴파일해줍니다. 변수는 가능하면 파일이나 함수의 선두에서 선언하고 정의하는 것이 좋습니다. 변수의 선언방식은 다음과 같습니다.

사용형식

자료형이름 변수이름 [= 초기치1] [,변수명2 [= 초기치2]] [,...];


보기

보기:

int n, m;

int n=1, m=3;

int n=1, m, a=3;


위의 보기는 정수형(int)인 변수이고 이름이 n이라는 변수와 m이라는 변수를 선언한 것입니다. 다른 말로 하면 n이라는 이름을 가진 변수를 앞으로 정수형 변수로 사용하겠다는 선언문이 되는 겁니다. 변수 선언을 해주면 컴파일러는 프로그램 실행시에 변수가 들어갈 자리를 미리 마련해둡니다. 하나의 문장에 여러 개의 변수를 동시에 선언할 수 있으나 각기 다른 자료형의 변수를 선언해서는 안됩니다. 그러니까 int n, m float a, b;라는 문장은 잘못된 것입니다.

변수를 선언하기 전에 가장 먼저 고려해야 할 점은 어떤 자료형의 변수를 선언할 것인가입니다. 그 변수가 담당할 기능에 따라서 정수형인지 문자형인지 결정해야 합니다.

// s03.cpp
#include

void main(void)
{
int a;
float b;
a = 3;
b = a/2;
printf("a=%d b=%f \n", a, b);
}


**그림: s03.cpp의 소스파일 내용

보기에서 a라는 변수는 정수형으로 선언을 했고, b라는 변수는 실수형으로 선언했습니다. a를 2로 나누면 1.5가 됩니다. 따라서 b라는 변수는 실수형으로 선언하는 것이 옳습니다. 만약 b도 정수형으로 선언했다면 a/2의 결과는 1이 되고 말겁니다.
이때 많은 사람들이 b를 실수형으로 선언했으므로 'b = a/2;'는 1.5가 될 것이라고 생각합니다. 그러나 'b = a/2;'는 1로 나옵니다. 이는 a가 정수이기 때문입니다. 정수를 정수로 나눈 결과도 정수가 된다는 점을 명심해야 합니다.


**그림: s03.exe를 실행시키면 엉뚱한 결과가 값으로 표시된다.

때문에 캐스트연산자를 이용하여 정수형 변수 a를 잠깐 실수로 바꾸어주어야 합니다. 그래서 'b = (float)a/2;'라고 적어야만 1.5라는 제대로 된 결과를 얻을 수 있습니다.

// s04.cpp
#include

void main(void)
{
int a;
float b;
a = 3;
b = (float)a/2;
printf("a=%d b=%f \n", a, b);
}


**그림: s04.cpp의 소스파일 내용


**그림: s04.exe가 올바른 결과를 보여주는 프로그램입니다.

변수는 선언과 동시에 대입연산자(=)를 이용하여 정의할 수 있습니다.

그리고 변수는 선언과 동시에 초기화를 할 수 있습니다. 즉 내용을 정의할 수 있습니다. 이때는 대입연산자 =기호를 사용합니다.


// s05.cpp
#include

void main(void)
{
int a=3;
float b=1.5;
printf("a=%d b=%f \n", a, b);
}


**그림: s05.cpp의 소스파일 내용



**그림: s05.exe의 실행 결과

변수의 선언 때 다른 변수를 사용할 수 없습니다.

이때 주의할 점은 변수를 선언하면서 동시에 정의할 때 다른 변수를 이용하면 안된다는 점입니다. 그러니까 float b=a/2; 라고 하면 잘못된 명령문이 되는 겁니다. 다른 변수를 이용하여 정의를 내리면 먼저 'float b;'라고 선언한 다음에 'b=a/2;' 라고 값을 초기화시켜야 합니다. 그러나 선언할 때는 다른 변수를 이용해서 정의할 수 없습니다.

**요약: 변수는 한 줄에 여러 개의 변수를 선언할 수 있으며 동시에 초기화할 수도 있는데, 반드시 같은 자료형이어야 합니다. 또한 선언과 동시에 정의할 때 다른 변수를 이용한 값을 대입시켜서는 안됩니다.


3.4.2. 정의한다? 초기화한다? 대입한다?


선언된 변수는 대입을 통해 어떤 값으로 채워주는데 이를 '정의한다'고 말합니다.

선언된 변수는 정의(definition)해주어야 합니다. 보통은 정의라는 말보다는 대입이라는 말을 더 많이 사용하는데 변수에 어떤 내용을 채워주는 행위를 말합니다.

보기

n=3;


위의 보기는 n이라는 변수에 3이라는 숫자를 대입하라는 뜻인데, 이것을 변수를 정의한다고 하고 다른 말로는 '변수를 초기화'한다고 말합니다. 즉 n이라는 변수의 내용을 3으로 초기화하는 셈입니다. 만약 나중에 'n=9;'라고 쓴다면 3을 버리고 9로 다시 초기화하는 셈입니다.

선언은 함수의 특성을 알려주고 정의는 주소를 배정받습니다.

변수의 선언과 정의에 대해서 혼동할 수도 있는데 선언은 변수가 사용될 것임을 미리 알리는 기능을 하고, 정의는 변수의 내용을 채운다는 뜻을 가지고 있습니다. 그렇기 때문에 선언에서는 생략가능한 것이 많습니다. 선언은 함수의 특성을 컴파일러에게 알려주는 역할을 하고, 정의는 변수를 위한 장소를 메모리(기억장소)에서 배당받도록 해줍니다.
예컨대 32평 짜리 아파트를 사고 싶다고 알려주는 것은 아파트 구입 선언에 해당합니다. 아파트 판매회사나 부동산업자는 이 선언을 통해 32평 짜리 아파트를 준비합니다. 우리가 컴파일러에게 'float money;'라고 선언하는 것을 통해 컴파일러는 32비트 짜리 크기의 변수라는 것을 알고 준비할 수 있습니다. 그리고 실제로 고객이 계약금으로 1000만원을 지불하면 32평 구입할 아파트를 배정해줍니다. 'money=1000;'이라는 명령문을 통해서 money라는 변수는 1000이라는 숫자를 저장할 공간을 배정받는 것이지요.

**요약: 선언한 변수에 어떤 값(상수)를 넣어주는 것을 정의한다 또는 대입, 초기화한다고 말하는데 이를 통해서 변수가 사용할 기억장소의 공간(주소)을 배정받습니다.


3.4.3. 변수가 차지하는 크기


변수의 선언을 통해 자료형의 크기에 맞는 자료를 컴파일러가 준비합니다.

변수를 선언한다는 말은 변수가 사용할 자리를 미리 만들어달라고 컴파일러에게 요청하는 의미와 같다고 말씀드렸습니다. 그럼 어느 정도 크기의 마련해야 할까요? 변수에 따라서 마련해야 할 자리의 위치나 크기가 조금씩 다릅니다. 자료형에 따라서 변수가 차지하는 크기는 다음의 표와 같습니다.

표: 하나의 변수가 차지하는 크기

+-----------------+---------+
| 키워드 |바이트수 |
+-----------------+---------+
| int | 2 |
| unsigned | 2 |
| long | 4 |
| unsigned long | 4 |
| char | 1 |
| unsigned char | 1 |
| float | 4 |
| double | 8 |
| long double | 10 |
+-----------------+---------+

이때 변수가 아닌 배열을 선언했다면 배열의 크기에 해당하는 크기를 마련해줍니다. 만약 배열의 크기를 함께 알려주었다면 지정한 크기만큼 공간을 확보합니다. 그러나 배열의 크기를 함께 알려주지 않았다면 컴파일러 임의로 적정한 공간을 마련해둡니다.

**요약: 변수의 크기는 변수의 자료형의 크기와 일치하며 배열의 크기는 지정한 배열 크기와 같습니다.


3.4.4. 변수와 상수


변수에는 변수의 자료형과 같은 자료형의 상수를 대입해야 합니다.

변수는 이름과 자리만 있을 뿐입니다. 변수의 공간에 들어갈 내용 즉 대입되는 값은 상수입니다. 따라서 변수의 자료형에 따라서 대입되는 상수의 자료형이 달라져야 합니다. 정수형 변수에는 정수형 상수만 대입해야 하고, 실수형 변수에는 실수형 상수를 대입해서 계산해야 합니다. 이미 앞서 자료형에 대해서 배웠으므로 같은 어떤 것이 같은 자료형인지는 잘 아실 것으로 생각합니다.

기억장소의 특성에 따라 변수는 자동으로 생성 소멸되기도 합니다.

유의해야 할 점은 기억장소에 따른 변수의 생성과 소멸입니다. 보통 함수 안에서 선언된 변수는 기본적으로 auto라는 기억장소를 가집니다. 기억장소에 대해서는 바로 이어서 설명을 드리겠지만 일단은 auto에 저장된 변수는 함수의 시작시에 스택이라는 메모리의 한 공간에 만들어졌다가 함수가 끝나면 자동으로 사라지는 것으로 보면 됩니다. 그러니까 함수와 함께 변수가 만들어졌다가 함수가 소멸되면 변수의 역할도 끝나므로 자동으로 변수를 메모리에서 제거해주는 겁니다.

그러나 함수 안에서 선언된 변수일지라도 기억장소를 static으로 설정해주면 힙이라는 메모리공간에 생성되므로 함수가 종료되어도 변수는 사라지지 않고 지속적으로 그 값을 유지하게 됩니다. 문자열이 대부분 static 기억장소를 사용하는데 이런 이유로 인해서 C++언어에서 모든 문자열은 포인터라는 것을 이용하여 제어하고 있는 것입니다.

그리고 변수의 자료형이 같지 않을 경우에는 보통 자동적으로 자료형을 통일한 다음 연산을 수행합니다. 그렇기 때문에 자료형의 자동변환 내용을 어느 정도는 파악하고 있어야 합니다.

표: 정수형 또는 double 형이 아닌 자료형의 변환방법

원래 자료형
변환된 자료형
변환조건
char
unsigned char
enum
float
int
int
int
double
부호를 확장해서 변환
상위 바이트를 0으로 변환
부호없는 형이면 unsigned 으로 변환
확장되는 가수부를 0으로 채우면서 변환


일반적으로 자료형의 변환은 산술 변환 우선 수위가 높은 쪽으로 변환합니다.

보통은 이항 연산자나 연산자나 삼항 연산자의 두 피연산자가 서로 다른 자료형일 경우에는 산술 변환 우선 순위가 높은 쪽으로 자료형을 변환합니다. 즉 정수형과 실수형이 있다면 정수형을 실수형으로 변환시킨다는 뜻입니다. 이를 프로모션이라고 합니다. 그리고 대입식에서는 오른쪽의 결과값이 왼쪽의 자료형으로 변환됩니다. 이때는 프로모션이 될 수도 있지만 반대로 산술 우선 순위가 낮은 자료형으로 변환되는 디모션이 될 수도 있습니다. 그리고 함수를 호출할 때에도 실매개 변수가 함수로 전달되면서 형변환이 일어납니다. 예를 들면 매개 변수의 문자형 자료는 정수형으로 변환되어 전달됩니다.

**요약: 서로 다른 자료형의 변수를 사용할 때는 자동적으로 형변환이 일어납니다. 일반적으로는 우선 순위가 높은 쪽으로 형변환이 일어나는 프로모션이 일어나지만 대입식에서는 우선 순위가 낮은 쪽으로 자료형 변환이 이루어지는 디모션이 일어날 수도 있습니
다.




첫줄로(go top, go first line) 문화원첫화면으로(go dal site home) 강좌차림으로(go Chair) 사이트맵으로(go sitemap)




total chairpost