포인터, 더 엄밀한 포인터
Last edit on 2023-10-23
A pointer is a variable that contains the address of a variable
- K&R C, second edition (1988)
포인터는 변수의 주소를 담은 변수다. 그 이상을 논의하기 이전에 먼저 알아볼 것이 있다.
int *pa;
우리는 기초로 돌아와, 위의 코드가 문법적으로 무엇을 의미하는지 다시금 상기해볼 필요가 있다. 기본적으로 C의 문법 체계에서 변수의 선언은 다음의 문법형식을 따른다.
type name
name
은 type
형임을 선언하는 코드다.
그렇다면, int *pa
는 무슨 의미일까?
똑같이, *pa
는 int
형임을 명시한다.
(K&R C는 이에 대해 이러한 문법이 mnemonic하다고 설명한다)
int *pa, *pb;
*pa
형이 int
임을 명시했기에 pa
가 int
의 포인터가 되는 것이지,
pa
형이 int*
형이기에 *pa
가 int
형인것은 아니다.
원인과 결과가 역전된 꼴이다.
*
가 형식 뒤에 붙지 않고, 변수 선언 앞에 붙는 이유중 하나다.
연산
int* pa;
pa + 1;
*(pa + 1);
3, 4번째줄을 보면, pa에 정수를 더하는 모습인데, 이는 어셈블리어에서처럼 1바이트씩 더함이 아닌, *pa의 자료형의 크기, 즉 4(전형적으로) 바이트씩 더해주게 된다.
int* pa;
pa - 1;
*(pa - 1);
마찬가지로, 뺄셈도 정의된다. *pa의 자료형의 크기, 즉 4(전형적으로) 바이트씩 빼주게 된다.
마지막으로, 포인터와 포인터간의 뺄셈이 정의된다. 포인터와 포인터 사이에 얼마나 많은 공간이 존재하는지 알려준다.
예외
딱 하나 예외가 있는데, 바로 void*
형이다.
K&R C에서 소개하기를, void*
형은 generic한 포인터로,
기본적으로 직접 역참조 할 수 없다.
K&R C는 memcpy
, memset
등 generic한 포인터가 필요한 구간에서
char*
를 사용하지 말고, void*
를 사용하기를 권장하고 있다.
용어 정리
int *pa;
위처럼 선언된 변수 pa를, pa is a pointer to int
라고 부르며,
한국어로 pa는 int형의 포인터
라고 부른다.
pa = &a;
pa points to a
라고 부르며,
한국어로 pa
는 a
를 가리킨다고 부른다.
*pb = *pa;
*pa = 0;
위처럼 *포인터변수
(본 코드에서는 *pa
)와 같이 작성하는 것을 indirection
(간접참조) 혹은 dereferencing
(역참조)라고 부른다.