반응형

※ 이 글은 본인이 이해한 것을 저장용으로 정리한 것으로 오류가 있을 수도 있습니다.


[포인터 정리] 2차원 구조체포인터를 함수에 인자로 전달 / 링크드리스트 / 해시테이블

링크드리스트(linked list)로 해쉬 테이블(Hash Table) 만들기




이러한 링크드리스트(Linked List)를 만든다고 하자 ( 해시테이블(Hash Table)을 만들때 주로 사용되는 형태이다)


예시를 보자(편의를 위해 불필요한 부분은 생략하였다)


typedef struct linkedlist* lptr;

typedef struct linkedlist{

int value;

lptr next;

}linkedlist;


int main(){

lptr* hashtable;

hashtable = (lptr*)malloc(sizeof(lptr)*20);

for(int i=0;i<20;i++)

hashtable[i] = NULL;

}


위의 세팅을 기본으로 하고 함수에 인자를 넘기면 경우마다 어떻게 되는지 정리해보겠다.

(Push하는 함수를 linkedlist_push라고 하자


1. linkedlist_push( hashtable[index], value);

2. linkedlist_push( &(hashtable[index]), value);


내가 가장 헷갈렸던 것이 위의 두 경우인데 비슷하면서 매우 다르다.


void linkedlist_push([자료형 미정] head, int value)


라는 함수에서 만약 head가 NULL인지 확인을 하고 NULL일 경우 세팅을 해주려면 2번을 사용하여야한다(head의 값을 바꾸려면!).

이유는 어떻게 보면 매우 단순한데 우리가 


int a = 5;


random_function(a);

random_function(&a);


위처럼 단순한 int값을 넘길때와 같다. a를 넘기면 그 값이 넘어가지만 그 값을 변경해봐야 그 함수의 지역변수를 바꾸는 것으로 함수를 벗어나면 의미가 없어진다. 우리가 의도하는 대로 a의 값을 바꾸려면 주소값을 넘겨서 변경하여야한다.


위의 예제도 같다.

아래의 그림을 참고하자




1번의 경우 hashtable이라는 배열의 한 칸의 주소값을 넘겨준다. 따라서 *head = (lptr)malloc(sizeof(linkedlist))로 바꾸면 적용이된다.

하지만 2번의 경우 lptr형식이긴 하지만 int a를 넘긴것 처럼 내용물을 넘긴것으로 head = (lptr)malloc(sizeof(linkedlist))를 하여도 head라는 지역변수에 저장되어 함수를 벗어나면 찾을 수 없다.


헷갈릴수도 있는 부분이 만약 첫 칸이 무조건 있다고 가정을 하고 연결되는 다음칸을 추가하는 것이라면 2방법 둘다 가능하다. head의 노드의 주소값을 통하여 next를 접근하든, 내용물의 next를 접근하든 같은 주소를 접근하기 때문이다.


즉, head의 값을 직접적으로 바꾸는 것이 아니라면 상관이 없다.




















반응형
블로그 이미지

개발자_무형

,