드디어 4강입니다. 수고하셨습니다.
많은 분들이 포인터를 어려워 한다고 들었고 그렇게 생각합니다.
하지만 저는 포인터가 전혀 어렵지 않다고 생각합니다.
지레 겁먹지 말고 보세요. 진짜 쉽다니까요?
int a = 1;
int *p;
p = &a;
printf ("%d",p);
printf ("%d",*p);
*p = 2;
위에 코드를 봅시다. a라는 변수를 만들고 1로 만들었습니다.
int *p라는 것이 포인터입니다. int *b 이런식으로 포인터를 만드는 거죠.
그리고 만든 포인터에 a의 주소값을 넣습니다. (&a)
처음 프린트되는건 뭘까요, 당연히 p에다가는 a의 주소를 넣었으니 a의 주소가 나오겠죠.
그 다음 프린트 되는건? 1이 나옵니다. * 라는 기호가 p에 있는 주소값에 가라는 의미입니다.
*p = 2;도 마찬가지로 *이 저장된 주소에 가란 소리니까 a가 2로 바뀌게 됩니다.
여러분이 헷갈려 하시는건 이 부분 입니다.
포인터를 선언할때 int *p;의 *와, 그 다음에 쓸때 *는 완전히 다른겁니다.
기호만 같을 뿐, 같은 역할이 아니죠.
int *p;의 *는 포인터를 만든다, 라는 의미이고, *p = 1;할때 *는 저장된 주소로 가라, 라는 의미이죠.
그런데 아주 헷갈릴만도 할것이,
int *p;
p = &a;
를 합쳐서 int *p = &a; 라고 쓸 수 있다는 겁니다.
당연히 a의 주소값은 p에다가 넣어야죠. p = &a;가 맞습니다.
그냥 두 문장을 합칠때만 그렇게 쓴다는걸 알아둡시다.
포인터의 개념은 이게 끝입니다. 정말로요.
이제는 포인터를 쓰는 다른 방법을 알아봅시다.
예전에 어레이를 만들때 arr[5] 를 만들었으면 왜
arr[0], arr[1], arr[2], arr[3], arr[4]
가 만들어 지듯이 왜 0부터 만들어지나 궁금했을 겁니다.
어레이에 포인터를 줘 봅시다.
int arr[5] = {1,3,5,7,9};
int *p;
p = arr;
저번 어레이에서 arr 과 &arr[0]은 같다고 배웠죠? 이거 모르면 큰일입니다. 정말.
*p를 하면 뭐가 나올까요? 1이 나옵니다. arr[0]의 주소를 줬으니까요.
어레이의 장점은 쉽게 만들고 쓸 수 있다는 점 뿐만 아니라 주소상으로도 연결 되있다는 점입니다.
*(p+1) 은 3이 나오게 됩니다. arr[1]과 똑같죠.
(p+1)이 뭘까요? p에는 arr[0]의 주소가 입력되어있죠. 거기에 1을 더한겁니다.
우리가 포인터를 처음 만들때 int *p라고 만들었죠. int를 표기할 포인터를 만든겁니다.
int *p는 1을 더하면 int에 맞춰서 자동으로 다음 1칸 옆으로 이동합니다.(4바이트 옆)
char *p라고 하면 1바이트 옆으로 이동하겠죠. 예를 들어 name[0] 에서 name[1]로 넘어가죠.
위 코드에서 *(p+1)은 arr[1]과 같습니다. 그래서 어레이가 0부터 시작되는거죠.
*(p+1)이라 치기 귀찮다면 그냥 p[1]이라 쳐도 됩니다. 이걸 컴파일러가 *(p+1)이라 인식하죠.
이러고 보니 포인터와 어레이가 참 비슷하지 않습니까?
사실 엄청 비슷합니다. 다른점은 어레이는 처음 만들어질때 크기가 정해져있고 주소를 못바꾼다는 점이죠.
사실상 같은 개념으로 생각해도 괜찮습니다.
이제 펑션에서도 포인터를 사용해 볼까요?
void square (int *p)
{
*p = (*p)*(*p);
}
int main()
{
int a = 3;
square (&a);
printf ("%d",a);
....
펑션에 있는 int *p는 square(&a)를 받았으니 p = &a;입니다.
어레이랑 마찬가지로 주소값을 받았으니 직접 수정이 가능하죠.
지금부터는 좀 이해하기 싫어질 겁니다. 점수를 좀 더 잘 받고싶으면 봅시다.
어레이를 100개, 1000개, 10000개 이렇게 만들다 보면 상당한 메모리가 필요합니다.
쓴 메모리는 지울 수 없을까요?
아예 처음부터 다이나믹 메모리를 할당합시다. <stdlib.h> 가 필요합니다.
int *p = (int*)malloc(4);
이러면 4바이트가 만들어지고 p가 그걸 가리키고 있네요.
(int*)malloc(sizeof(int)*8);
sizeof(int) 는 int 의 사이즈입니다. sizeof(char) 이런식으로도 가능하죠.
int 8개를 만들었으니 p[8]을 선언한것이랑 똑같습니다.
이렇게 잘 사용하고 난뒤 다른 데이터를 위해 이 메모리를 없애줘야겠죠?
free(p);
free(*p)가 아닙니다. free(p)라고 쓰면 아까 선언한 sizeof(int)*8이 없어집니다. 메모리 상에서요.
그 다음 포인터 p가 가르키고 있는것을 없애줘야 합니다. 포인터가 엉뚱한데를 가르키고 있으면 위험하거든요.
p = NULL;
이렇게 하면 됩니다.
'여러가지' 카테고리의 다른 글
sublime text에서 컴파일 후 실행할때 cmd로 열기 (0) | 2015.05.14 |
---|---|
3ds 다운그레이드 & 에뮤낸드 (0) | 2015.01.31 |
기말고사 대비 프기실 3강. Array (0) | 2014.12.15 |
기말고사 대비 프기실 2강. Structure (0) | 2014.12.14 |
기말고사 대비 프기실 1강. Function (0) | 2014.12.11 |