Post

포인터 뿌셔보기

포인터에 대해 집중 탐구를 해봐염.

포인터가 뭐임?

*는 포인터 선언으로 해당 변수의 메모리 주소값을 참조하는 용도로 사용할 수 있다. 그 후 변수의 메모리 주소값을 얻고 싶을 땐 & 연산자를 사용한다. 그러고 메모리 주소에 있는 실제 값을 가져오거나 변경하고 싶으면 다시 *를 써서 역참조 용도로 사용한다.

포인터가 왜 필요한데?

애초에 우리가 코드를 작성할 때 변수를 선언하고 사용하면 그게 다 어디에 저장되는가? 메모리에 저장된다. 더 자세한건 여기서

그래서 그 값의 메모리 주소값을 사용하고 싶을 때는 포인터(*)와 주소 연산자(&)를 사용하는거다.

포인터를 사용하는 경우는 주로

  1. 변수간의 값을 서로 바꿔야 될 때나,
  2. 연결리스트를 구현해야 될 때 등 다양한 용도에서 쓰인다.

코드로 살펴보자

말로 하면 이해 되는 것 같은데 막상 코드를 보면 아니다.

고로 예제 코드를 몇 가지 봐보자.

먼저 변수 서로간의 값을 바꿀 때는 아래처럼 swap 함수를 만들 수 있다.

swap()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
void swap(int* p, int* q);
int main(void) {
    int a = 4;
    int b = 5;
    swap(&a, &b);
    printf("A: %d, B: %d", a, b);
    return 0;
}
void swap(int* p, int* q) {
    int temp = *p;  // temp에 p가 가리키는 값을 저장 (주소가 아님)
    *p = *q;    // p가 가리키는 위치에 q가 가리키는 값을 저장
    *q = temp;  // q가 가리키는 위치에 temp 값을 저장
}

근데 왜 굳이 포인터를 사용한 함수를 만들어서 쓰는걸까? 이에는 크게 2가지 이유가 있다.

  1. 여러번 사용할 수 있으니까.

만약 값을 한 번만 바꿀거면 그냥 main문 안에다가

1
2
3
4
5
int a = 4;
int b = 5;
int temp = a;
a = b;
b = temp;

temp 변수 하나 만들어서 여기에 임시로 a값 저장하고 a에 b값 씌우고 b에 temp값 씌우면 된다.

근데 값을 여러번 바꿔야되면? 이 부분을 일일히 복붙해서 수정해서 적을건가?

아니지 않는가. 그래서 함수를 쓰는거다.

두번째 이유는

  1. 함수에는 return 값이 하나밖에 올 수 없으니까 포인터를 매개변수로 받아서 함수 내에서 원본 변수 값을 바꾸는거다.

만약 포인터 없이 그냥 아래처럼 함수를 작성하면

1
2
3
4
5
void swap(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
}

변수간에 값이 안 바뀐다.

왜냐면 main함수에서 실행 된 변수는 함수 컨택스트니까 스택 구간에 저장된다. 근데 swap도 함수다. 고로 얘도 스택 구간에 저장된다. 근데 이 swap에 저장되는 주소값하고, main에서 저장되는 주소값하고는 다르다. 그냥 값만 복사하는거다.

결론적으로 주소값이 다 다르기 때문에 동일한 메모리 주소에서 받아와서 값을 변경해주기 위해서 포인터를 사용해서 주소를 갖고오고 연산자로 그 주소의 값을 불러오는거다.

사실 다른 언어에서도 포인터는 다 존재한다. 다만 숨겨져있는 것일뿐.

참고자료

http://cslibrary.stanford.edu/102/PointersAndMemory.pdf

This post is licensed under CC BY 4.0 by the author.