많은 전공학생들과 개발에 입문한 사람들에게 멘붕을 선사하는 악명높은 포인터이다.
필자도 처음 접했을때 이해는 했지만 디테일한 이해가 부족해 다시볼때마다, 혹은 코드에 적용할때마다
이해의 깊이가 깊게 들어가지 못하고 겉도는 듯한 느낌이 자주들었다.
Pointer 란?
포인터는 메모리주소를 할당받는 변수이다.
주소는 말 그대로 다른객체(주로 변수)의 메모리상의 위치이다.
A pointer is a variable that holds a memory address.
This address is the location of another object (typically another variable) in memory.
포인터를 사용하면 동적 할당이 가능해지는데 이는 몇몇 루틴에 있어서 더 나은 효율성을 제공한다.
Pointers can improve the efficiency of certain routines.
잘못 사용하면 굉장히 위험해지기도 하는 c/c++ 의 구조이기도 한데 이는
Smart Pointers 를 사용하면 해결 할 수 있다.
(스마트 포인터가 아닌 포인터는 Raw pointer 이다)
Pointers are one of the strongest but also one of the most dangerous features in C/C++
The C++ introduced smart pointers to reduce the complexity and danger (potential) of raw pointers.
원리

예를 들어 1000이라는 메모리 주소에 할당된 x 변수가 있다고 생각해보자.
또한 y 변수는 1003 이라는 메모리 주소에 할당됐다고 생각해보자.
코드로 보자면
int y = 20;
int *x;
이 x 변수에 1003 에 할당된 변수의 주소를 선언 할 수 있다.
코드로 보자면
x* = &y;
가 될 것이다.
& <- 이놈은 ~의 주소 라는 뜻으로 해석 하면된다.
이 코드에서 만약 x++; 를 추가한다면
x 는 1004 주소를 가르키게 된다.
반대로 x--; 를 추가하면 1002를 가르키게 될 것이다.
여기서 문제를 하나 내보겠다.

이 코드의 답은 어떻게 나올지 5초만 생각해보고 스크롤 하길 바란다.
답은
x 의 메모리 주소 y 의 메모리 주소
5 6
이 나온다.
포인터와 배열의 관계
아래의 코드가 있다고 가정해보자
char arr[80], *p;
p = arr;
위의 코드의 의미는
p 는 arr 배열의 첫번째 값 즉 arr[0] 의 주소가 할당되어있다는 의미이다.
여기서 만약 arr 의 5번째 값에 접근하고 싶다면
arr[4] 도 가능하겠지만 포인터를 사용한다면
*(p+4) 가 될 것이다.
머리가 어지럽기 시작 할 수 있다.
만약 그렇다면 그냥 문법이다. 라고 생각하고 외우길 바란다.
배열과 포인터 심화
int 만 받는 포인터 배열을 선언 할 수도있는데 이는
int *x[10];
로 선언 할 수 있다.
만약 6이라는 숫자를 배열의 3번째에 추가하고 싶다면
int var = 6;
x[2] = &var;
로 추가 할 수 있다.
쉽게 생각하자면 평범한 배열에 변수를 넣고싶을땐 그 변수 자체를 넣고
포인터 배열에 변수를 넣고싶을땐 변수의 주소를 할당하면된다.
그냥 외워라.
여기서 문제 하나를 더 내보겠다.
저 포인터 배열 *x[10] 의 3번째에 할당되어있는 int 를 꺼내서 int c; 에 할당 하고 싶다면 어떻게 하면 되겠는가?
정답은
c = *x[2];
로 할당하면 된다.
포인터 변수는 앞에 asterisk(*) 를 붙이지 않으면 메모리주소를 뱉게되고 붙이면 할당된 객체를 뱉어내기 때문이다.
그래서 도대체 왜 쓰는데???
이 머리 쪼개질 것 같이 만드는 말도안되는 기능을 왜 쓸까?
대표적인 이유로는 동적할당(dynamic allocation)을 사용 할 수 있어
메모리 관리를 효율적으로 할 수 있다 라고 말하고싶지만
입문자들 입장에선 무슨 개소리인가 싶을 것이다.
동적할당(dynamic allocation)과 정적할당(static allocation)에 대해선 다음 포스팅에서 다루도록 하겠다.
이는 재처두고 이해하기 쉬운 사용 예시를 보여주고 포스팅을 마치겠다.

CS 기본지식이 있는 사람이라면 눈치챘겠지만 결과는

이렇게 나올 것이다.
위 x y의 값은 바뀌지 않는다.
이를 Pass by value 라고 하는데
한마디로 함수 바깥의 변수를 바꾸거나 재선언 하고싶을때 (즉 main 에 선언된 x, y)
Pass by value 를 사용하면 바뀌지 않는다.
Variables define outside the scope of the function and passed to the function as parameters will not have their values changed if passed by value.
이때 포인터를 사용한 함수를 사용한다면?

이를 Pass by reference 라고 부르며 값은

이렇게 아름답게 바뀌게 된다.
한마디로 포인터를 사용한 Pass by reference 를 사용하게 된다면 함수 스코프 바깥에 선언된 변수조차
변경 할 수 있게된다.
If we pass a pointer to the variable we can then change the value even though the variable was declared outside of the function/method
'개인공부 > 자료구조와 알고리즘' 카테고리의 다른 글
| Tree(트리 구조) (2) | 2023.02.06 |
|---|---|
| Linked List(링크드 리스트) (1) | 2022.07.20 |
| Stack (스택) (0) | 2022.07.19 |
| List (리스트) (0) | 2022.07.17 |