C언어) 형 한정자

Lapis0875·2022년 10월 21일
0

c언어

목록 보기
10/21
post-thumbnail

❓형 한정자?

형 한정자는 변수의 사용을 제한하기 위해 사용해요. 기억영역 클래스 뒤와 자료형 앞에 사용해요.

🔑const

const 형 한정자를 사용한 변수는 초기화는 가능하지만, 그 후에 새 값을 할당하거나 증가, 감소, 수정될 수 없어요.

const double pi = 3.14;

pi = 3.141592;		// 앞서 초기화되었기 때문에 값을 수정할 수 없어요.

const 변수라 하더라도, 포인터를 사용해 값을 변경할 수 있어요.

const int answer = 10;
int *p = &answer;		// 컴파일러가 경고해줘요.
*p = 42;
printf("answer = %d\n", answer);		// 42

위 코드를 컴파일하면, 포인터 변수 p를 초기화 하는 부분을 컴파일러가 경고해줘요.

위 코드를 실행해보면, answer의 결과가 10이 아닌 42로 포인터에 의해 변경된 것을 볼 수 있어요.
그렇다면, const 변수를 안전하게 포인트 하려면 어떻게 해야 할까요?
포인터 변수를 const로 만들어 해결할 수 있어요.

const int answer = 10;
const int *p = &answer;
*p = 42;		// 오류 발생

const로 선언한 포인터 변수 p 자체는 상수가 아니지만, p에 역참조 연산자를 사용해 원본을 변경할 수 없어요.

🔑restrict (C99)

C99에 추가된 restrict 형 한정자는 포인터 변수에 사용할 수 있어요.
restrict를 사용하면, 현재 포인트 되는 객체는 다른 포인터에 의해서는 포인트 되지 않음을 명시할 수 있어요. restrict 형 한정자는 컴파일러가 코드 최적화를 수행하는데 도움을 줘요.

아래 코드는 두 int형 포인터를 인자로 받는 swap_int 함수에요.

void swap_int(int *a, int *b)
{
	int tmp = *a;
    *a = *b;
    *b = tmp;
}

두 메모리 주소에 저장된 값을 바꾸는 함수이니, 같은 주소의 경우는 바꿀 필요가 없어요. 따라서, 명시적으로 각각 다른 주소임을 restrict를 사용해 명시할 수 있어요.

int swap_int(int * restrict a, int * restrict b)
{
    if (a == b) return EOF;

    int tmp = *a;
    *a = *b;
    *b = tmp;
}

restrict 형 한정자를 적용해서, 컴파일러에서 최적화가 이루어지는걸 어셈블리 등으로 확인할 수 있는 사례를 찾고있어요! 혹시나 좋은 사례가 있다면, 댓글로 공유해주세요 😉


배운 내용들을 정리해보고 있어요. 잘못 기재된 내용이 있다면, 댓글로 지적해주시면 수정할게요.

profile
새내기 대학생 개발자에요 :D

0개의 댓글