2013-09-29 3 views
1

이것은 여기에서 나의 첫 번째 질문입니다. 이 프로그램에서 몇 줄의 코드를 이해할 수 없습니다.사용자 정의 파괴 (무료) 기능

사용자 정의 파괴 함수 포인터는 내가 이해할 수없는 것입니다.

저는 코드에 도움이 필요한 "도움이 필요합니다 # 1 도움이 필요합니다"라고 말했습니다.

어떤 도움을 주시면 감사하겠습니다. 본인이이 코드를 이해하도록 도와 줄 수있는 사람에게 정말 감사 할 것입니다. 여기

#ifndef LIST_H 
#define LIST_H 
#include <stdio.h> 

typedef struct _ListElmt 
{ 

    void *data; 
    struct ListElmt *next; 

} ListElmt; 
typedef struct _List 
{ 

    int size; 
    int (*match)(const void *key1, const void *key2); 
    void (*destroy)(void *data); 

    ListElmt *head; 
    ListElmt *tail; 

} List; 

void list_init(List *list, void (*destroy)(void *data)); 

void list_destroy(List *list); 

int list_ins_next(List *list, ListElmt *element, const void *data); 

int list_rem_next(List *list, ListElmt *element, void **data); 

int list_size(const List *list); 

ListElmt *list_head(const List *list); 

ListElmt *list_tail(const List *list); 

int list_is_head(const ListElmt *element); 

int list_is_tail(const ListElmt *element); 

void *list_data(const ListElmt *element); 

ListElmt *list_next(const ListElmt *element); 
#endif 

및 1

생성에 링크 된 목록에 전달 된 인수 destroypointer to a function이다 질문 번호

#include <stdlib.h> 
#include <string.h> 
#include "List.h" 

/* Need Help #1: The destroy function pointer is called here when the list is initialized and I need some explanation on how this works */ 

void list_init(List *list, void (*destroy)(void *data)) 
{ 

    list->size = 0; 
    list->destroy = destroy; 
    list->head = NULL; 
    list->tail = NULL; 

    return; 
} 

void list_destroy(List *list) 
{ 

    void *data; 

    while (list_size(list) > 0) 
    { 

    if (list_rem_next(list, NULL, (void **) &data) == 0&& list->destroy != NULL) 
    { 

     list->destroy(data); 

     /* Need Help #2: The above line - how this works. I have no idea how this works because I haven't seen any code like that before. Also kindly let me know if this is recursion or not.*/ 
    } 
    } 
    memset(list, 0, sizeof(List)); 
    return; 
} 

int list_ins_next(List *list, ListElmt *element, const void *data) 
{ 

    ListElmt *new_element; 

    if ((new_element = (ListElmt *) malloc(sizeof(ListElmt))) == NULL) // not yet understanded 
    return -1; 

    new_element->data = (void *) data; 

    if (element == NULL) 
    { 
    if (list_size(list) == 0) 
     list->tail = new_element; 

    new_element->next = list->head; 
    list->head = new_element; 
    } 

    else 
    { 
    if (element->next == NULL) 
     list->tail = new_element; 

    new_element->next = element->next; 
    element->next = new_element; 
    } 

    list->size++; 
    return 0; 
} 

int list_rem_next(List *list, ListElmt *element, void **data) 
{ 

    ListElmt *old_element; 

    if (list_size(list) == 0) 
    return -1; 

    if (element == NULL) 
    { // Handle removal of the head 

    *data = list->head->data; 
    old_element = list->head; 
    list->head = list->head->next; 

    if (list_size(list) == 1) 
     list->tail = NULL; 
    } 

    else 
    { // Handle removal from somewhere else 

    if (element->next == NULL) 
     return -1; 

    *data = element->next->data; 
    old_element = element->next; 
    element->next = element->next->next; 

    if (element->next == NULL) 
     list->tail = element; 
    } 

    free(old_element); 

    list->size--; 
    return 0; 
} 
+1

가능한 복제본 [C에서 함수 포인터는 어떻게 작동합니까?] (http://stackoverflow.com/questions/840501/how -do-function-pointer-in-c-work) – Shahbaz

+0

도움을 원하지만 명확한 질문은 무엇입니까? – Tonmoy

답변

3

list.c입니다. 링크 된 객체가 보유하고있는 객체를 파괴하여 메모리를 확보하는 방법을 알지 못합니다. 그래서 그 행동을 수행하기 위해 외부로부터 무언가가 필요합니다. 따라서 사용자는 목록에 저장 한 객체의 메모리를 해제하는 방법을 알고있는 함수를 작성하고 링크 된 목록에 노드를 삭제해야 할 때 해당 함수를 사용하도록 지시해야합니다.

함수에 대한 포인터가 목록 변수 destroy에 저장됩니다. 질문 # 2

함수에 대한

당신은 단지라고 할 수있는 포인터를 통과하고 점유 메모리를 확보하기 위해 현재 노드에 저장된 데이터에 대한 포인터를 전달되고있는 것이다.

이 기술은 command or action pattern라고

0
  • #의 help1을 = 아무것도가 호출되지 않습니다 (단지 OOP에 제한되지 않는다!) 함수 포인터는 다음에 만 할당됩니다. 할당 후 list->destroy에 destroy 함수의 주소가 포함됩니다.
  • # HELP2 : 이제 함수가 호출 = func(arg)이 함수 호출이며, fncptr 유형을
  • #의 HELP3 함수에 대한 포인터 인 경우 그래서, funcptr(arg)입니다 : = memset(list, 0, sizeof(List));이 거짓 NULL 포인터 값으로 표시되어 있다고 가정 모두 0입니다. 반드시 그럴 필요는 없습니다. (대부분의 경우 그렇지만 아키텍처는 NULL에 대해 다른 표현을 가질 수 있습니다.)