79.4 레지스터 변수 사용하기
변수를 선언할 때 앞에 register를 붙이면 변수는 메모리 대신 CPU의 레지스터를 사용합니다. 따라서 일반 변수보다 속도가 빠릅니다. 단, 레지스터는 개수가 한정되어 있으므로 register를 붙인다고 해서 모두 레지스터를 사용하지는 않습니다.
- register 자료형 변수이름;
register.c
#include <stdio.h> #include <stdlib.h> // malloc, free 함수가 선언된 헤더 파일 int main() { register int num1 = 10; // 변수 num1은 CPU의 레지스터를 사용 printf("%d\n", num1); // printf("%p\n", &num1); // 컴파일 에러. num1은 메모리에 없으므로 메모리 주소를 구할 수 없음 // error C2103: 레지스터 변수에 '&'이(가) 있습니다. register int *numPtr = malloc(sizeof(int)); // 레지스터 변수에 메모리 주소는 저장할 수 있으므로 역참조 연산자를 사용할 수 있음 *numPtr = 20; printf("%d\n", *numPtr); // 20 free(numPtr); return 0;
실행 결과
10 20
레지스터 변수는 변수가 CPU 레지스터만 사용하므로 메모리에는 생성되지 않습니다. 따라서 &로 메모리 주소를 구할 수 없습니다. 단, 레지스터 변수에 메모리 주소는 저장할 수 있으므로 역참조 연산자 *를 사용할 수 있습니다.
레지스터 변수는 반복 횟수가 매우 많을 때 유용합니다.
register int i, j; for (i = 0; i < 1000000; i++) { for (j = 0; j < 10000; j++) { } }
제 컴퓨터에서 이 코드로 100억 번을 반복할 때 레지스터 변수를 사용하면 2.8초, 레지스터 변수를 사용하지 않으면 16.8초가 걸렸습니다(리눅스 GCC에서 컴파일했습니다. 사용하는 컴퓨터, 운영체제, C 언어 컴파일러에 따라 실행 시간은 다를 것입니다).
register는 지역 변수에만 사용할 수 있고 전역 변수에는 사용할 수 없습니다.
참고 | 형 한정자
C 언어는 기억 부류 지정자 이외에 형 한정자(type qualifier)라는 것도 있습니다.
키워드 | 설명 |
---|---|
const | 값을 변경할 수 없음 |
volatile | 변수를 사용할 때 항상 메모리에 접근하도록 만듦 |
restrict | 메모리 접근 횟수를 줄이는 최적화를 함 |
_Atomic | 여러 스레드에서 변수를 사용할 때 변경한 값이 정확히 적용되도록 보장(원자적 연산) |
const는 'Unit 10 상수 사용하기', volatile은 '85.15 volatile 변수', restrict는 '85.16 restrict 포인터'를 참조하세요. _Atomic은 Visual Studio 2022에서 사용할 수 없으며 이 책에서는 다루지 않습니다.