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
'프로그래밍 언어 > C, C++의 기본적인 설명' 카테고리의 다른 글
[C언어 라이브러리] stdlib.h (0) | 2022.09.10 |
---|---|
[C 언어 라이브러리] iso646.h (0) | 2022.09.08 |
[C언어] C 언어 레퍼런스 및 학습 순서 정리 (1) | 2022.03.28 |
[C 언어] 함수와 가변 전달 인자 (0) | 2022.03.26 |
[C 언어] 명령행 전달인자 (argc, argv) (0) | 2022.03.25 |
댓글