저번 시간에 포인터 변수에 대해 배웠습니다. 오늘은 구조체 포인터를 써 보도록 하겠습니다. 사실, 링크드 리스트 구현할 때 상당히 많이 쓸 거에요. 예를 들어서 p->next? 아니면 p->prev? 이런 식으로 많이 쓰실 건데요. ->가 무엇인지도 오늘 알아보도록 하겠습니다.

 

 


 먼저 main 함수 안에 point형 구조체 변수가 선언이 되어 있다고 해 봅시다.

 

 

 

 8번째 줄에 point형 지역 변수인 p를 선언했습니다.

 

 

 그러면 메모리에는 위와 같이 할당이 될 겁니다. 맞나 모르겠네요. 그러면, 메모리의 어느 위치에, p를 위한 공간이 만들어 진 거에요. 역참조도 할 수 있을까요? 주솟값만 알고 있다면, 그것을 통해서 간접 참조를 할 수 있을 텐데요.

 

 

 9번째 줄을 보면, t에 p의 주솟값을 넣고 있습니다.

 

 

 그러면 메모리에 다음과 같이 할당이 됩니다. t라는 지역 변수가 있는데, 이것은 p의 주솟값 가지고 있더라. 그렇기 때문에 t는 p를 가리키고 있다. 구조체 변수를 가리키고 있어요. 그러면 무엇인가요? 구조체 포인터입니다. 어렵지 않네요. 배열을 가리키고 있으면 배열 포인터. 함수를 가리키고 있으면 함수 pointer. 어렵지 않아요.

 

 

 이제 11번째 줄을 해석해 볼게요. 보시면 t는 p의 주솟값이라고 했어요. 그러면 (*t)는 무엇을 의미하나요? p의 주솟값을 통해서 역참조한다는 의미입니다. 그러면 real_data인 p가 될 거에요.

 

 

 그러면 (*t).x는 무엇을 의미할까요? p.x와 똑같습니다. 즉, 변수 p의 필드 x를 의미합니다.

 

 

 그러면 (*t).y는 무엇을 의미할까요? p의 필드 y를 의미합니다. 즉 p.x에 1을, p.y에 2를 넣는다는 의미입니다. 12번째 줄을 수행하면 1 2가 출력됩니다. 그런데, t->x, t->y로 쓸 때도 (*t).x, (*t).y와 동일한 의미가 됩니다. 이는 t가 가리키는 곳의 필드 x, t가 가리키는 곳의 필드 y에 접근하겠다는 의미입니다.

 

 

 출력 결과는 1 2입니다.

 

 


 기본 예제 1가지만 더 보겠습니다. 이름과 age가 있는 people 구조체를 생각해 봅시다. 우리는 people에, 이름과 age를 넣는, data_fill 함수를 작성해야 한다고 생각해 봅시다.

 

 

 그러면 함수 원형은 다음과 같을 겁니다. main 함수를 봅시다.

 

 

 people형 지역변수인 p가 선언이 되었습니다. 그리고 저는 data_fill에, p의 주솟값을 1번째 인자로, 2번째 인자로 20을, 3번째 인자로 "abcd"라는 문자열을 넘겨 주었는데요. 이것을 그림으로 그려보면 아래와 같습니다.

 

 

 그러면, data_fill 함수의 p는, main의 p를 가리키고 있어요.

 

 

 그러면 data_fill 함수에서, 그러니까 17번째 줄의 p->age는 어떤 의미일까요? main 함수에 할당이 된 p의 age 필드를 의미합니다. p->name은 무엇을 의미할까요? main에 선언된 p의 name 필드를 의미합니다. 즉, main의 p 변수에 각각 a와 name을 채워 넣는 함수임을 알 수 있어요.