c언어 매개변수

조회수 470회

링크드 리스트에서 탐색할 때는 아래처럼 ListNode *p 변수를 만들어서 탐색하는데,

void print_list(ListNode *head)
{
    for(ListNode *p = head ; p != NULL ; p = p->link)
        printf("%d->",p->data);
 }

반복적 트리 탐색에서는 따로 TreeNode* t 를 만들지 않고 그냥 매개변수node를 그대로 사용합니다

TreeNode* searh(TreeNode* node, int key) 
{ 
  while (node != NULL) { 
    if (key == node->key) 
    return node; 
    else if (key < node->key) 
    node = node->left; 
    else 
    node = node->right; 
 } 
 return NULL; 
} 

책에 원본 변수의 복사본이라 괜찮다고 나와있는데 왜 링크드 리스트 때는 ListNode *p 를 만들어서 쓴 건지 잘 모르겠습니다 링크드 리스트도 마찬가지로 원본에 영향 없는 거 아닌가요?

3 답변

  • 좋아요

    0

    싫어요
    채택 취소하기

    로컬 포인터변수가 쓸데없이 왜 있느냐는 질문 같네요.

    맞습니다. 필요 없어 보입니다.

    가독성면에서, 변수명을 head 로 해서, 리스트 전체의 head 를 인자로 주도록 하는 편이 함수를 사용할 때 혼동을 줄일 수 있어서, head 로 명명했을 것 같고, head 로 이름지었는데, 그걸 계속 바뀌는 노드를 표현하는 변수로 쓰기가 "가독성"관점에서 좋지 않아서, 로컬변수를 하나 마련했다고 생각됩니다.

    • 답변 감사합니다 anderson 2020.11.9 19:52
  • 리스트는 노드의 연결 집합으로서, 노드 구조체 변수와 리스트 구조체 변수가 각각 존재해야 합니다.

    그러나 트리의 경우에는, 트리 자체가 재귀적인 형식의 자료구조입니다. 그래서 트리 노드 자신이 트리이기도 합니다.

    그러므로 리스트에서는 노드 변수, 리스트 변수를 각각 제어해 주는 경우가 있고요. 트리는 트리 변수가 트리 그 자체이므로 트리 변수만 제어해 주면 됩니다.

    이러한 내용을 읽고 계신 책에서도 아마 강조하고 있을 것입니다.

    질문하신 코드에서, 리스트 코드의 경우에는 리스트가 노드의 연결체이므로 리스트의 첫 노드의 주소값을 넣어주면 첫 노드부터 쭉 찾아 들어가면서 값을 출력하도록 해 놓은 코드이고요.

    트리의 코드는, 트리가 이미 구성되어 있다면 트리의 서브 트리 주소가 left와 right 변수에 이미 저장되어 있기 때문에, 트리의 루트 노드의 주소값을 매개변수로 넣고 계속 내려가면서 key 값을 갖는 노드를 찾는 코드입니다.

    • (•́ ✖ •̀)
      알 수 없는 사용자
    • 답변 감사합니다 anderson 2020.11.9 19:52
  • 제가 크게 착각을 했습니다. 혼란을 드려 죄송합니다.

    daewon님 말씀대로 head = head->link에서 바뀌지 않습니다.

    아래처럼 리스트의 주소값을 받아 내부의 헤드 변수를 이용한다면(보통 이렇게 사용하지 않겠지만) 바뀔수 있습니다.

    void print_list(List *plist)
    {
        for(; plist->head != NULL; plist->head=plist->head->link)
            ...
    }
    
    void print_list(ListNode *head)
    {
        for(ListNode *p = head ; p != NULL ; p = p->link)
            printf("%d->",p->data);
     }
    

    위 경우에는 우선 head에 저장된 주소값을 p에 복사한 후에 p의 값을 변경하는 일반적인 코드입니다. 그래서 head의 값이 바뀌지 않고요.

    위와 같이 복사해서 쓰지 않고, 질문하신 것처럼 아래와 같이 그냥 head를 이용한다면 함수 호출시 넘겨준 주소값이 바뀌어 버립니다. head = head->link에서 바뀝니다.

    void print_list(ListNode *head)
    {
        for(; head != NULL ; head = head->link)
            printf("%d->",head->data);
     }
    

    보통 head는 리스트의 머리를 뜻하기 때문에, 값을 출력할 때에는 책처럼 head 포인터 변수를 복사해서 사용하시고 수정하시면 안됩니다.

    리스트의 머리쪽에 값을 새로 넣거나 리스트의 머리쪽 노드를 지우는 경우에만 head를 변경합니다.

    • (•́ ✖ •̀)
      알 수 없는 사용자
    • 함수 내에서만 바뀌고 메인함수의 진짜 head 주소는 그대로이지 않나요? anderson 2020.11.9 21:00
    • head = head->link 라고 해도, 함수를 호출한 쪽에서는 변경이 없어요. nowp 2020.11.10 03:02
    • 제가 크게 착각을 했습니다. 혼란을 드려 죄송합니다. 알 수 없는 사용자 2020.11.10 11:45
    • 아닙니다 ! 시간 내주셔서 감사합니다 anderson 2020.11.10 16:42

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)