2017-06-19 184 views
-1

我有這樣的結構:如何用void *數據創建結構體?

struct node 
{ 
    int data; 
    struct node *next; 
}; 

所以下面strcut有一個int數據,我希望函數接受CopyFunction這是baisicly指針接受無效*的函數,返回void *,我想我的函數獲取第一個節點中的數據副本連接到第二個數據副本f,現在我希望數據不僅是int我想在任何數據上使用此函數,所以我使用CopyFunction作爲指向函數的指針

struct node 
    { 
     Element data; 
     struct node *next; 
    }; 

typedef void* Element; 

typedef Element (*copy_function) (Element); 


struct node * concatLists(struct node *head1, struct node *head2, int cmp(struct node *),copy_function CopyFunction) 
{ 
    struct node *head = NULL; 
    struct node **current = &head; 

    for (; head1 != NULL; head1 = head1->next) 
    { 
     if (cmp(head1)) 
     { 
      *current = malloc(sizeof(struct node)); 
      (*current)->data = CopyFunction(head1->data); 
      (*current)->next = NULL; 
      current = &(*current)->next; 
     } 
    } 

    for (; head2 != NULL; head2 = head2->next) 
    { 
     if (cmp(head2)) 
     { 
      *current = malloc(sizeof(struct node)); 
      (*current)->data = CopyFunction(head2->data); 
      (*current)->next = NULL; 
      current = &(*current)->next; 
     } 
    } 
:那我Saied如何接受void *的...我如何能在功能波紋管,如果我想改變結構是使用..例如10

,然後,如果我有一個INT結構,我可以只使用此功能和複印功能於這樣的INT:

static void* copyInt(void* num){ 
    int* newInt=malloc(sizeof(*newInt)); 
    *newInt=*(int*)num; 
    return newInt; 
} 

此外,我認爲這是更好的,如果我改變,並且不使用總是結構節點*我想有可能:typedef struct node_t * Node;

+0

這看起來像一個[XY問題(http://xyproblem.info/) –

+0

PS - 「name_t」形式的類型是保留的。 – ikegami

回答

1
concatLists(..., (copy_function)copyInt) 

提供了所有的 「方法」(cmpCopyFunction)作爲參數變得傻快。爲什麼不創建一個List「對象」持有不只是一個指針的頭部和尾部,但「辦法」過於泛化的列表。

cmp可能是一個比較功能(這意味着它應該用兩個參數),這意味着你可能想合併排序名單。那麼,這裏是使用通用列表實現來做到這一點的代碼。 (我想我還不如讓mallocfree插式爲好。)

#include <stdio.h> 
#include <stdlib.h> 

// ----- 
// ListNode type declarations. 

typedef struct ListNode { 
    void* data; 
    struct ListNode* prev; 
    struct ListNode* next; 
} ListNode; 

// ----- 
// ListType type declarations. 

typedef void* (* Allocator )(size_t); 
typedef void (* Deallocator )(void*); 
typedef void (* FreeFunction)(void*); 
typedef int (* CmpFunction )(void*, void*); 
typedef void* (* CopyFunction)(void*); 

typedef struct { 
    Allocator malloc; 
    Deallocator free; 
    FreeFunction free_data; 
    CmpFunction cmp; 
    CopyFunction copy; 
} ListType; 

// ----- 
// List type declarations. 

typedef struct { 
    const ListType* list_type; 
    ListNode* head; 
    ListNode* tail; 
} List; 

typedef void (*ListVisitor)(void*); 

// ----- 
// ListDataInt definitions. 

static void* ListDataInt_new(int i) { 
    int* ip = malloc(sizeof(int)); 
    *ip = i; 
    return ip; 
} 

static void ListDataInt_free_data(int* ip) { 
    free(ip); 
} 

static int ListDataInt_cmp(const int* ap, const int* bp) { 
    if (*ap < *bp) return -1; 
    if (*ap > *bp) return +1; 
    return 0; 
} 

static int* ListDataInt_copy(const int* orig_ptr) { 
    int* new_ptr = malloc(sizeof(int)); 
    *new_ptr = *orig_ptr; 
    return new_ptr; 
} 

static const ListType ListDataInt_list_type = { 
    malloc, 
    free, 
    (FreeFunction)ListDataInt_free_data, 
    (CmpFunction)ListDataInt_cmp, 
    (CopyFunction)ListDataInt_copy 
}; 

// ----- 
// ListNode definitions. 

static ListNode* ListNode_new(List* list, void* data) { 
    const ListType* list_type = list->list_type; 

    ListNode* node = list_type->malloc(sizeof(ListNode)); 
    node->data = data; 
    node->prev = NULL; 
    node->next = NULL; 
    return node; 
} 

static void ListNode_free(List* list, ListNode* node) { 
    const ListType* list_type = list->list_type; 

    list_type->free_data(node->data); 
    list_type->free(node); 
} 

// ----- 
// List definitions. 

static List* List_new(const ListType* list_type) { 
    List* list = list_type->malloc(sizeof(List)); 
    list->list_type = list_type; 
    list->head = NULL; 
    list->tail = NULL; 
    return list; 
} 

static void List_free(List* list) { 
    ListNode* next = list->head; 
    while (next != NULL) { 
     ListNode* node = next; 
     next = node->next; 
     ListNode_free(list, node); 
    } 

    list->list_type->free(list); 
} 

static void List_push(List* list, ListNode* node) { 
    if (list->tail == NULL) { 
     list->head = list->tail = node; 
    } else { 
     list->tail->next = node; 
     node->prev = list->tail; 
     list->tail = node; 
    } 
} 

static void List_push_data(List* list, void* data) { 
    List_push(list, ListNode_new(list, data)); 
} 

static void List_visit(List* list, ListVisitor visitor) { 
    for (ListNode* node = list->head; node != NULL; node = node->next) { 
     visitor(node->data); 
    } 
} 

// ----- 
// Main program. 

static List* merge_sorted_lists(List* list1, List* list2) { 
    const ListType* list_type = list1->list_type; 

    List* new_list = List_new(list_type); 

    ListNode* src1 = list1->head; 
    ListNode* src2 = list2->head; 
    while (src1 != NULL && src2 != NULL) { 
     int cmp = list_type->cmp(src1->data, src2->data); 
     if (cmp <= 0) { 
      List_push(new_list, ListNode_new(new_list, list_type->copy(src1->data))); 
      src1 = src1->next; 
     } 

     if (cmp >= 0) { 
      List_push(new_list, ListNode_new(new_list, list_type->copy(src2->data))); 
      src2 = src2->next; 
     } 
    } 

    while (src1 != NULL) { 
     List_push(new_list, ListNode_new(new_list, list_type->copy(src1->data))); 
     src1 = src1->next; 
    } 

    while (src2 != NULL) { 
     List_push(new_list, ListNode_new(new_list, list_type->copy(src2->data))); 
     src2 = src2->next; 
    } 

    return new_list; 
} 

static void dumper(const int* ip) { 
    printf("%d\n", *ip); 
} 

int main(void) { 
    List* sorted_int_list1 = List_new(&ListDataInt_list_type); 
    List_push_data(sorted_int_list1, ListDataInt_new(4)); 
    List_push_data(sorted_int_list1, ListDataInt_new(6)); 
    List_push_data(sorted_int_list1, ListDataInt_new(8)); 

    List* sorted_int_list2 = List_new(&ListDataInt_list_type); 
    List_push_data(sorted_int_list2, ListDataInt_new(5)); 
    List_push_data(sorted_int_list2, ListDataInt_new(7)); 
    List_push_data(sorted_int_list2, ListDataInt_new(9)); 

    List* merged_sorted_int_list = 
     merge_sorted_lists(sorted_int_list1, sorted_int_list2); 

    List_visit(merged_sorted_int_list, (ListVisitor)dumper); 

    List_free(sorted_int_list1); 
    List_free(sorted_int_list2); 
    List_free(merged_sorted_int_list); 
    return 0; 
} 

測試:

$ gcc -Wall -Wextra -pedantic --std=c99 -o a a.c && a 
4 
5 
6 
7 
8 
9