< Reveiw >
포인터는 주소를 저장하는 변수라고 정의 했습니다. 이때 포인터 변수가 4byte 메모리 공간을 사용하므로 4개의 주소를 사용합니다. 그렇다면 포인터 변수의 시작주소를 저장하려면 어떤 포인터 변수에 저장해야 할까요?
(힌트)
- int 형 변수의 주소는 int * 형 변수에 저장한다.
- char 형 변수의 주소는 char * 형 변수에 저장한다.
- int * 형 변수의 주소는 int * * 형 변수에 저장한다.
- char * 형 변수의 주소는 char * * 형 변수에 저장한다.
1, int형과 포인터
n은 정수를 저장하는 변수(메모리)이며, pn은 int형 주소를 저장하는 변수(메모리)이며 ppn은 int*형 주소를 저장하는 변수(메모리)입니다. 아래 그림을 참고하세요.
- ppn에 * 붙인 *ppn은 pn 메모리가 됩니다.
- pn에 * 붙인 *pn은 n 메모리가 됩니다.
- *ppn에 * 붙인 **ppn은 n 메모리가 됩니다.
위 내용을 확인하는 코드입니다.
void main( )
{
int n = 100;
int *pn = &n;
int **ppn = &pn;
printf("%x %x %x\n", &n, pn, *ppn);
printf("%x %x \n", &pn, ppn);
printf("===================\n");
printf("%d %d %d\n", n, *pn, **ppn);
}
- 12ff60 12ff60 12ff60
12ff54 12ff54
===================
100 100 100
위 그림을 이해 했다면 어렵지 않습니다.
int n에서 n은 변수(정수, 값을 저장하는)입니다.
int *pn에서 pn은 포인터입니다.(싱글 포인터라고도 합니다.)
int **ppn에서 ppn은 포인터의 포인터라합니다.(더블 포인터라고도 합니다.)
int ***pppn에서 pppn은 포인터의 포인터의 포인터라합니다.
...
부르기 힘들죠? 그래서 우리는
int *pn에서 pn은 1차 포인터라고 합니다.
int **ppn에서 ppn은 2차 포인터라고 합니다.
int ***pppn에서 pppn은 3차 포인터라고 합니다.
...
pn이 저장하는 &n은 1차 주소라고 합니다.
ppn이 저장하는 &ppn 2차 주소라고 합니다.
pppn이 저장하는 &ppn은 3차 주소라 합니다.
꼭 정리하고 기억하세요~!
또 한가지 정리하고 가야합니다. 값(value)와 address(주소)입니다. 메모리 정리를 보시면 아시겠지만 메모리 내의 내용물을 값이라고 합니다. 한마디로,
- n에 저장되어 있는 정수 10도 값(value)입니다.
- pn에 저장되어 있는 주소 &n(12ff60)도 pn의 값(value)입니다.
- ppn에 저장되어 있는 주소 &pn(12ff54)도 ppn의 값(value)입니다.
하지만 그것은 컴퓨터의 일반적인 메모리에서의 이야기이며 보통 C언어에서는,
- n에 저장되어 있는 정수 10을 값(value)라합니다. (raw value라고도 합니다.)
- pn에 저장되어 있는 &n(12ff60)은 값이라 하지 않고 그냥 주소라고합니다. -> 12ff60은 숫자만의 의미가 아닌 int형 주소의 의미이며 데이터이기 때문입니다.
- ppn에 저장되어 있는 &pn(12ff54)도 값이라 하지 않고 그냥 주소라고합니다. -> 12ff54도 숫자만의 의미가 아닌 int*형 주소의 의미이며 데이터이기 때문입니다.
한마디로 기본 자료형 변수의 저장된 내용물만 값(value)라 하고 포인터 변수에 저장된 내용물은 주소라 합니다. * 연산자와 []연산자를 보여주는 예제입니다.
void main( )
{
int n = 100;
int *pn = &n;
int **ppn = &pn;
int ***pppn = &ppn;
printf("%d %d %d\n", *pn, **ppn, ***pppn);
printf("%d %d %d\n", pn[0], ppn[0][0], pppn[0][0][0]);
}
- 100 100 100
100 100 100
모두 100이 출력됩니다. *pn은 pn[0]와 같습니다. 우리 눈에는 달라도 컴파일러 눈에는 같다고 했습니다. 혹 기억이 안나시면 앞 페이지를 참고하세요.
- * *pn은 pn[0][0]와 같습니다.
- * **pn은 pn[0][0][0]와 같습니다.
그러나 여기서 어떤 연산자를 사용할까요? 두 연산자 모두 사용 가능하지만 여기서는 []연산자 보다 *연산자를 사용하는게 좋습니다. []연산자는 주소를 기준으로 여러 메모리를 접근할 때 사용합니다. 조금만 공부해 보시면 알겠지만 주소로 메모리의 내용을 접근할 때 *연산자를 사용하는게 좋을 때가 있고 []연산자를 사용하는게 좋을 때가 있습니다.
2, char형과 포인터
void main( )
{
char c = 'A';
char *pc = &c;
char **ppc = &pc;
printf("%c %c %c\n", c, *pc, **ppc);
printf("%x %x %x\n", &c, pc, *ppc);
}
- A A A
12ff63 12ff63 12ff63
여기까지입니다. ^^
.....
댓글 없음:
댓글 쓰기