728x90
기억 클래스
기억 공간
- 변수를 선언한 후에 변수를 사용할 수 있다.
- 변수 선언을 하는 이유는 메모리에 변수의 기억 공간 영역을 확보하기 위해서다.
- 변수의 기억공간을 얼마만큼 확보할 것인지는 자료형에 의해서 결정
- 변수를 어떻게 선언하느냐에 따라서 유효 범위와 생존 기간 등 변수의 성격이 달라진다.
- 변수의 유효 범위와 생존 기간은 기억 클래스에 의해서 결정
- 세분화된 데이터 영역에 변수가 어디에 어떻게 확보될지는 기억클래스에 의해서 결정
- 모든 변수들이 동일한 기억 공간에 할당되는 것은 아니다.
- 기억공간(RAM 구조)
기억클래스
종류 | 유효 범위 | 생존 기간 | 메모리 | 초기화 여부 |
auto(자동 변수) | 블록 내 | 일시적 | 스택 | 쓰레기 값 |
extern(외부 변수) | 프로그램 내 | 영구적 | 메모리 | 숫자 0 |
static(정적 변수) | 내부 : 블록 내 외부 : 모듈 내 |
영구적 | 메모리 | 숫자 0 |
register(레지스터 변수) | 블록 내 | 일시적 | CPU 내의 레지스터 | 쓰레기 값 |
- 유효 범위 : 변수가 사용될 수 있는 영역
- 생존 기간 : 변수가 메모리의 기억 공간을 차지하고 있는 기간
- 일시적 : 변수가 선언된 시점에 생성되었다가 블록 종료 시 자동 소멸. 프로그램 내에서 생성과 소멸이 여러 번 반복
- 영구적 : 프로그램이 시작할 때 생성되어 프로그램 실행 중에 항상 메모리 상의 동일한 기억 공간에 존재. 프로그램이 완전히 끝날 때 비로소 변수가 소멸
변수
변수 선언 형식
변수 선언 기본 형식 | 변수 선언 사용 예 |
[기억클래스] 자료형 변수명; | auto int a = 0; |
- 변수 선언은 자료형과 기억 클래스에 의해 2가지로 구분
- 자료형에 의한 구분 : 생략할 수 없으며 변수에 저장되는 값의 형태와 기억공간의 크기를 결정(int, char, float 등)
- 기억 클래스에 의한 구분 : 생략할 수 있으며 생략할 경우 auto로 인식. 유효 범위와 생존 기간 등 변수의 성격을 결정(auto, extern, static 등)
자동변수
- 지금까지 사용한 변수. 즉, 가장 일반적으로 사용하는 형태의 변수
- 자동변수는 auto라는 기억클래스를 붙이지 않고 생략한 채로 사용
- 자동 변수는 함수 정의부 안에 선언된 변수, 함수의 매개변수도 자동변수에 포함
- 프로그램이 실행되는 동안 생성과 소멸을 반복
- 변수 선언이 된 블록 밖으로 벗어나면 메모리가 해제되어 변수를 사용할 수 없게 된다.
- 2개의 서로 다른 함수에서 동일한 이름의 변수를 선언해서 사용 가능
- 지역 변수이기 때문에 변수를 함수 안에서 선언하면 변수 선언을 한 함수 안에서만 인식되어 사용되기 때문
- 서로 다른 블록({}으로 묶이는 코드)에서도 같은 원리가 적용되므로 같은 이름의 변수를 각각 선언해서 그 영역에서만 사용 가능
- 자동변수와 스택
- C++ 컴파일러는 자동변수가 선언되면 스택에 메모리를 할당
- 자동변수는 프로그램을 수행하는 동안 변수 선언을 만나면 생성되었다가 변수가 선언된 블록 밖으로 벗어날 때 소멸되는 일을 반복
- 스택은 LIFO(Last In First Out) 구조로 메모리의 일부를 잡아 새로 생성되는 변수를 차곡차곡 쌓아두었따가 맨 위에 있는 변수(가장 최근에 선언된 변수)를 사용
- 제거할 때에도 맨 위에 있는 것부터 제거
- 프로그램 수행 중에 기억공간이 생성과 소멸을 반복하지만 새로 생성된 기억공간을 자동 초기화하지 않으므로 프로그래머가 초기화하지 않으면 쓰레기값을 갖는다.
지역변수와 전역변수
- 지역 변수
- 블록({} 또는 함수) 안에 선언된 변수를 지역변수라 하며 변수를 사용할 수 있는 범위는 그 변수가 선언된 블록 내부로 한정
- 자동변수는 대표적인 지역 변수다.
- 전역 변수
- 변수 선언을 함수 외부에서 하는 경우
- 외부 변수는 대표적인 전역변수로서, 프로그램 내의 모든 함수에서 사용할 수 있는 변수
- 프로그램이 실행되는 동안 메모리 상에 항상 배치되므로 값이 유지
- 자동으로 초기화(수치 데이터라면 0으로)가 이루어진다.
- 전역변수와 지역변수의 이름이 같을 경우에 지역변수가 기본적으로 적용
- 주의 사항
- 지역변수
- main 함수 내에 선언한 지역변수들은 main 함수 내에서만 사용할 수 있기 때문에 사용자 정의 함수에서는 사용할 수 없다.
- 그래서 함수에 매개변수가 있는 것
- 또한, main 함수에 선언된 변숫값을 사용자 정의 함수에서 변경하려면 단순히 매개변수만을 사용하는 것만으로는 불가능하고, 포인터나 참조 변수를 사용해서 주소에 의한 호출이나 참조에 의한 호출 기법을 사용해야 가능하다.
- 전역변수
- 매개변수를 사용하지 않고도 모든 함수에서 사용 가능
- 전역변수는 쉽고 간단한 접근을 허용하는 대신에 프로그램의 신뢰성에 문제
- 따라서, 데이터의 무결성이 잘 보존되도록 필요한 경우에만 데이터에 접근할 수 있도록 하는 것이 좋음
- 지역변수
정적 변수
- 변수 선언할 때 변수명 앞에 static을 붙이면 정적변수로 선언
- 지역변수로서의 정적변수와 전역변수로서의 정적변수가 있고, 변수 선언을 어디에 했는지에 따라 결정
- 지역변수로서의 정적변수 : 블록 내부에 선언
- 전역변수로서의 정적변수 : 블록 외부에서 선언
지역변수로서의 정적변수(자동변수와 지역변수로서의 정적변수)
변수명 | 구분 | 유효 범위 | 생존 기간 | 메모리 | 초기화 여부 | 변숫값 여부 |
auto | 자동 변수 | 블록 내 | 일시적 | 스택 | 쓰레기 값 | 유지 안 함 |
static | 지역변수로서의 정적변수 | 블록 내 | 영구적 | 메모리 | 숫자 0 | 유지한 |
- 지역변수로 선언한 정적변수와 자동변수(지역변수)의 유효 범위는 같다.
- 지역변수로 선언한 정적변수와 자동변수의 생존기간은 다르다.
- 자동변수는 변수의 생성과 소멸을 반복하는 스택에 기억공간이 할당되어 변수를 선언한 블록 내부에서만 생존하여 수명이 짧음.
- 정적변수는 메모리 영역에 기억 공간이 할당되어 생존기간이 프로그램의 생명주기와 동일
- 자동변수와 정적변수의 생명주기가 다른 점은 변수의 초기화에도 영향
- 자동변수는 명시적으로 개발자가 초깃값을 주지 않으면 쓰레기 값 저장
- 정적변수는 초깃값을 주지 않아도 int 형의 경우 0으로, double 형인 경우 0.0으로 컴파일러에 의해 자동으로 초기화
- 명시적으로 초기화 했을 경우 변숫값 유지 여부
- 자동변수
- 자동변수는 함수가 호출되는 시점에서 메모리 할당이 일어나서 초기화되고 함수가 종료되면 기억공간이 소멸된다.
- 다시 함수가 호출되면 또다시 메모리 할당이 일어난다.
- 함수가 호출될 때마다 변수가 초기화되어 이전의 값을 유지하지 않는다.
- 정적변수
- 함수의 호출과 상관없이 프로그램이 시작되는 순간 변수가 생성되고 이때 초기화 됨.
- 한번 생성된 정적변수는 정적변수가 선언된 함수의 실행이 종료되어도 소멸되지 않기 때문에 다음에 그 함수가 다시 여러 번 호출하더라도 더 이상 새롭게 초기화가 일어나지 않아 메모리에 그 값이 기억되어 있다.
- 즉, 함수를 호출할 때마다 리셋되지 않고 이전의 값을 유지하고 있다.
- 자동변수
#include <iostream>
using namespace std;
void sub(); //함수의 선언
void main()
{
for(int i = 1; i <= 5; i++){
cout << i << "===>\n";
sub(); //함수의 호출
}
}
void sub() //함수의 정의
{
int a = 0; //자동 변수
static int b = 0; //정적 변수
a += 100;
b += 100;
cout << "auto a = " << a << endl;
cout << "static b = " << b << endl;
}
- a는 자동변수이므로 함수가 호출될 때마다 변수 a가 새로 생성되며 그 때마다 초깃값을 0으로 지정
- b는 정적변수이므로 프로그램이 시작하자마자 변수가 생성되어 초깃값이 0으로 지정되며 함수의 호출이 일어날 때마다 static b = 0; 이란 선언한 부분은 무시되고 수행된 값을 변수 b가 누적한다.
- 따라서 자동변수 a는 함수가 호출되어 변수 선언문을 만날 때마다 새로 생성됨과 동시에 0이라는 값으로 초기화되므로 0에 100을 더해서 100이 된다.
- 정적변수 b는 누적된 값에 100을 더하기 때문에 500까지 증가한다.
전역변수로서의 정적변수(외부변수와 전역변수로서의 정적변수)
- 외부 변수(전역변수)
- 하나의 프로젝트로 묶여있는 모든 파일(코드) 내에서 공유해서 사용할 수 있는 변수를 외부 변수라 한다.
- 다른 파일에 선언된 외부 변수에 접근하려면 사용하기 전에 참조하겠다는 의미로 예약어 extern을 덧붙여 변수를 선언한 후 사용
- ex. extern int a;
- extern을 지정하지 않으면 다른 파일에 정의된 외부변수를 사용할 수 없다.
- extern의 의미는 따로 기억 공간을 할당 받는 것이 아니라 이미 다른 파일에 선언된 변수를 참조하겠다는 의미
- extern이 붙은 변수 선언에서는 초깃값을 줄 수 없다.
- 전역변수로서의 정적변수
- 전역변수로서의 정적변수를 함수 외부에서 선언하게 되면 전역변수로서의 성격을 갖게 되므로 어느 함수에서나 사용 가능
- 단, 전역변수로서의 정적변수는 그 변수가 선언되어 있는 파일에서만 사용할 수 있다.
- 즉, 파일 하나에서만 사용할 수 있는 전역변수가 필요하다면 함수 외부에 변수를 선언할 때 static을 붙이면 된다.
- ex. static int a;
레지스터 변수
- 변수를 선언할 때 자료형 앞에 register라는 예약어를 덧붙이면 레지스터 변수로 선언
- ex. register int a;
- 레지스터 변수는 자동변수와 모든 면에서 동일하다.
- 자동변수가 스택에 기억공간을 할당하는 데에 비해 레지스터 변수는 CPU 내의 레지스터에 자리를 잡는다.
- CPU 레지스터를 사용하는 이유는 스택에 접근하는 것보다 빠르기 때문이다.
- 하지만 CPU 내의 레지스터는 제한되어 있으므로 기억클래스 register를 붙이더라도 레지스터가 여분이 없을 경우 자동변수처럼 스택에 자리를 잡는다.
'C++ > 이론' 카테고리의 다른 글
[C++] 함수(2) (0) | 2024.09.24 |
---|---|
[C++] 함수(1) (5) | 2024.09.20 |
[C++] 무한 루프 (for문, while문, goto문) (0) | 2023.10.01 |
[C++] 보조 제어문 (break문, continue문) (0) | 2023.09.30 |
[C++] 반복문 (for문, while문) (0) | 2023.09.29 |