포인터를 쓰는 이유 - sihyun10/data_structures_docker GitHub Wiki
개요
ListNode *cur = ll->head;
ListNode *prev = NULL;
왜 *를 사용해 포인터 변수로 선언해야하는걸까?? 하며 궁금증이 생겼다.
아래 내용은 이 궁금증으로 찾아보게 된 내용이다.
포인터란? (다시 개념 잡고 가기)
int a = 10;
int *p = &a;
p는 정수 변수 a의 주소를 저장하는 "포인터 변수"
즉 p는 a를 가리키고 있다.
ListNode *cur = ll->head;
- cur : ListNode 구조체를 가리키는 포인터 변수
- 연결 리스트의 어떤 노드를 가리키는 용도로 사용하려면 "포인터"를 활용해야한다
그렇다면 왜 포인터로 해야할까?
연결리스트는 노드를 연결해서 사용하는 자료구조이다
각 노드가 다음 노드를 가리키는 포인터(next)를 갖고 있고,
포인터를 사용해야 리스트를 따라가면서 조작할 수 있게 된다
즉 연결리스트처럼 "원본을 따라가야 하는 구조"에선 포인터를 활용해야한다!
원본을 따라가야 하는 구조
어떤 데이터를 복사해서 따로 쓰는게 아닌, 진짜 원본 데이터를 직접 다뤄야하는 상황인 경우!
1. 값을 복사하는 경우
int a = 10;
int b = a; //복사
b = 20;
printf("%d", a); //10
b는 a의 값을 복사한거다
그래서 b를 바꿔도 a에는 영향 X
2. 포인터로 원본을 따라가는 경우
int a = 10;
int *p = &a; //p는 a의 주소를 저장
*p = 20;
printf("%d", a); //20
p는 a를 가리키는 "포인터"이다
*p = 20은 a의 값도 바뀌게 된다
즉 원본을 따라가서 바꾼다는 의미이기도 하다
이게 왜 연결리스트랑 관련이 있는건데?
연결리스트는 예시를 간단히 들어보자.
[2] -> [4] -> [6] -> NULL
각 노드는 다음 노드를 가리키는 포인터(next)를 가지고 있다
그리고 리스트를 순회하려면 그 포인터를 계속 따라가야 순회가 가능하다
//예시 코드
ListNode *cur = ll->head;
while (cur != NULL) {
printf("%d ", cur->item);
cur = cur->next;
}