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)라는 것도 있습니다.

표 79-2 형 한정자
키워드 설명
const 값을 변경할 수 없음
volatile 변수를 사용할 때 항상 메모리에 접근하도록 만듦
restrict 메모리 접근 횟수를 줄이는 최적화를 함
_Atomic 여러 스레드에서 변수를 사용할 때 변경한 값이 정확히 적용되도록 보장(원자적 연산)

const'Unit 10 상수 사용하기', volatile'85.15 volatile 변수', restrict'85.16 restrict 포인터'를 참조하세요. _Atomic은 Visual Studio 2022에서 사용할 수 없으며 이 책에서는 다루지 않습니다.