본문 바로가기
프로그래밍 언어/C, C++의 기본적인 설명

[C 언어] 기억 부류, 연계, 수명, 한정자

by Physics 2022. 4. 10.
728x90

1. 기억 부류, 연계 및 수명

일반적으로 C에서 변수는 다음 3가지 특성으로 기술이 된다
  (1) 수명 (Storage duration)
  (2) 범위 (scope)
  (3) 연계 (linkage) 

특성 설명
수명 - 해당 변수가 얼마동안 메모리에 유지하는가 
• 수명의 종류: 정적 수명 (static storage duration), 자동 수명 (automatic storage duration) 
 1) 정적 수명: 프로그램이 실행되는 동안 내내 존재 
   -- 파일 범위 변수의 경우, 정적 수명을 지님 
범위 • 해당 변수가 프로그램의 어느 부분이 이름에 의해 그 변수를 사용할 수 있는지를 나타냄
• 프로그램이 어떤 식별자에 접근할 수 있는 영역 
• 범위의 종류: 블록 범위, 프로토타입 범위, 파일 범위 
  (1) 블록 범위:
   - 여는 중괄호와 짝을 이루는 닫는 중괄호 안에 포함되어있는 코드 영역 
   - 블록 내에서 생성된 변수는 블록 범위를 가짐 
   - ex 1) for(int i = 1; i < 3; i++); 
   - ex 2) { int i = 0; i++;} // 해당 중괄호 이후에는 i가 해제됨
  (2) 함수 프로토타임 범위 
   - 함수 프로토타입에 사용되는 변수 이름에 적용 
   - 범위: 변수들이 정의된 지점부터 프로토타입 선언의 끝 
  (3) 파일 범위 
   - 범위: 자신이 정의된 시점으로부터 파일의 끝까지 
   - 파일 범위를 가진 변수들을 전역 변수 (global varible)이라고 부르기도 함 
연계 • 해당 변수가 프로그램의 어느 부분이 이름에 의해 그 변수를 사용할 수 있는지를 나타냄
• C에서 연계의 종류
  (1) 외부 연계 (external linkage) 
   - 파일 범위 변수는 외부 및 내부 연계 중 하나를 가질 수 있음 
   - 외부 연계를 가지는 변수는 여러 개의 파일로 구성된 프로그램 어디에서나 사용가능  
  (2) 내부 연계 (internal linkage) 
   - 파일 범위 변수는 외부 및 내부 연계 중 하나를 가질 수 있음 
   - 내부 연계를 가지는 변수는 한 파일의 안에서만 어디서나 사용이 가능 
  (3) 무연계 (no linkage) 
   - 블록범위변수나 프로토타입 변수 범위는 연계를 지니지 않음 

 

 

변수들의 종류 

변수 수명 범위 연계 기타
자동변수 자동 블록 무연계 - 키워드: auto 
- 블록 안에 선언 
- 블록을 벗어나면 자동 변수는 소멸되며, 이후 해당 메모리는 다른 용도로 사용될 수 있음
- 자동 변수는 사용자가 명시적으로 초기화를 하지않는 이상 dummy값이 할당됨 
레지스터 변수 자동 블록 무연계 - 키워드: register
- ex) register int example = 1; 
- 블록 안에서 키워드 register를 이용하여 선언 
- CPU 레지스터 또는 좀더 일반적으로 사용할 수 있는 가장 빠른 메모리에 저장됨 
- 보통의 변수들보다 더 빠르게 접근할 수 있고 처리될 수 있음 
- 레지스터 변수들은 메모리보다 레지스터에 저장될 가능성이 높음
  NOTE: 레지스터 변수로 선언한다고 해서 100%로 레지스터에 저장되는 것은 아님. 
- 그 이외의 나머지는 자동변수의 특성과 비슷 
- 해당 지정자를 이용하여 변수를 정의할 경우, 사용자는 해당 변수의 주소를 얻을 수 없다. (주소연산자 &를 사용하여 주소를 얻을 수 없음)
블록범위 정적 변수  정적 블록 무연계 - 키워드: static 
- 정적: 변수가 그대로 유지됨을 의미 
- 블록 안에서 static으로 정의
- 한번의 호출에서 다음번의 함수 호출까지 그 값을 기억함 
- 프로그램이 실행되는 동안, 그 변수를 포함하는 블록이 사용되고 있지않더라도 그 값을 계속 유지함 
- 함수의 매개변수에는 static을 사용할 수 없음 
외부 연계 정적 변수 정적 파일 외부 - 키워드: extern 
- 외부 기억 부류 (external storage class)라 부름 
- 이 부류에 속하는 변수들을 외부 변수(external variable)라 부름
- 외부 변수는 어떤 함수에도 속하지 않게 함수의 외부에 정의 선언을 한다. 
- 모든 함수들의 바깥에 선언
- 어딘가에 이미 정의되어있는 변수를 재선언한다는 것을 의미 
- 해당 변수가 다른 파일에 정의가 되어있다면, 반드시, extern 키워드를 사용하여 그 변수를 정의해야 한다.
- 선택적인 재 선언을 할 경우, 해당 변수들을 사용한다는 의도를 문서화하는 용도로 사용됨 
- 외부 변수의 경우, 자동 변수와 다르게 사용자가 명시적으로 초기화를 하지 않아도 0으로 초기화됨 
- 만일 외부 연계 정적 변수와 같은 이름을 가진 변수를 extern 변수 없이 정의할 경우, 이름은 같지만 다른 변수가 정의됨
- 외부 변수는 단 한번만 초기화할 수 있음 
- ex) 
int tern =1; /*tern 이 정의가 됨 (정의선언)*/
int main(void){
   extern int tern; // 어딘가에 정의가 되어있는 tern을 사용함 (참조 선언)
   // 키워드 extern은 어디에 있는지 찾아보라고 컴파일러에게 지시하는 것이기 때문에 해당 선언은 정의가 아니라는 것을 나타냄. 외부 정의를 생성하려면 키워드 extern을 사용하면 안됨. 이미 존재하는 외부 정의를 참조하는 용도로만 초기화 할 수 있음

}
내부 연계 정적 변수 정적 블록 내부 - 키워드: static 
- 모든 함수들의 바깥에 static으로 정의 
- 내부 연계를 가지는 정적 변수는 같은 파일에 있는 함수들만 사용할 수 있음 
- 단 한번만 초기화 가능
- 만일 명시적으로 초기화되지 않을 경우 모든 바이트들이 0으로 설정

 

블록 범위 정적 변수의 예시 

#include <stdio.h>
void trystat(void);

int main(void){
    
    for (int count = 1; count <= 3; count ++){
    	printf("loop cycle: %d\n", count);
    	trystat();
    }
}

void trystat(void){
	int fade = 1;
    static int stay = 1;
    
    printf("fade = %d, stay = %d\n", fade ++, stay ++);
}
===========================================================
프로그램 실행 결과 
loop cycle: 1 
fade = 1, stay = 1
loop cycle: 2 
fade = 1, stay = 2
loop cycle: 3
fade = 1, stay = 3

- fade는 함수가 호출될 때마다 초기화됨 
- 정적 변수로 할당된 stay는 함수가 호출되더라도 fade와 다르게 초기화되지 않는다. 
- trystat() 함수만이 stay 변수를 인식할 수 있음 

 

2. 한정자

C에서는 데이터들의 특성을 수명, 범위, 연계로 구분을 했다. C90에서는 여기에 추가적으로 불변성(Constancy)과 휘발성(volatility)을 추가했다. 

다음은 C에서의 한정자이다. 

한정자 설명
const - C90이후부터 정의됨
 const 키워드는 그 변수를 대입 연산, 증가 연산, 감소 연산으로 값을 변경할 수 없도록 함 
 const 키워드 변수는 초기화 가능 
 const 키워드를 사용한 변수는 읽기 전용 변수가 되며, 한번 정의가 되면 그 값을 더 이상 변경할 수 없음 
자주사용하는 예시 
  1. 포인터에 const 사용하기 
  2. 전역 데이터에 const를 사용 
    (a) 첫번째 방법: 외부 변수에 적용되는 유용한 규칙을 따르는 것 
      - 하나의 파일에 정의 선언을 넣음 
      - 다른 파일들에는 extern 키워드를 사용하는 참조 선언을 사용하는 것 
     (Ex: extern const <variable>) 
    (b) 상수들을 include 파일에 넣는 것 
volatile - C90이후부터 정의됨
- 어떤 변수가 프로그램이 아니니 다른 대행자에 의해 그 값이 변경될 수 있다고 컴파일러에게 알림*
* 일반적으로 하드웨어 주소에 또는 동시에 실행된느 여러 프로그램들이 공유되는 데이터에 사용됨 
restrict - C99이후부터 정의됨
- 컴파일러가 특정 유형의 코드를 최적화할 수 있도록 허용함으로써 계산 능력을 향상시킴 
- restrict 키워드는 포인터에만 적용이 가능하다. 
- 함수 매개변수로 사용되는 포인터에도 사용이 가능함 
NOTE: 이 경우, 함수의 몸체 안에서 그 포인터가 가리키는 데이터를
 1) 다른 식별자로 수정할 수 없음 
 2) 다른 방법으로는 불가능한 최적화를 컴파일러가 시도할 수 있음  

 

728x90

댓글