Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何使用void*数据创建结构?_C_Pointers_Struct - Fatal编程技术网

C 如何使用void*数据创建结构?

C 如何使用void*数据创建结构?,c,pointers,struct,C,Pointers,Struct,我有这个结构: struct node { int data; struct node *next; }; 下面的strct有一个int数据,我希望函数接受CopyFunction,它实际上是一个指向接受void*并返回void*的函数的指针,我希望我的函数获得第一个节点中的数据副本,该节点连接到第二个数据的副本,现在我希望数据不仅仅是int,我想在任何数据上使用这个函数,所以我使用CopyFunction作为指向一个函数的指针,正如我所说,它接受void*。。。我如何在下面的

我有这个结构:

struct node
{
    int data;
    struct node *next;
};
下面的strct有一个int数据,我希望函数接受CopyFunction,它实际上是一个指向接受void*并返回void*的函数的指针,我希望我的函数获得第一个节点中的数据副本,该节点连接到第二个数据的副本,现在我希望数据不仅仅是int,我想在任何数据上使用这个函数,所以我使用CopyFunction作为指向一个函数的指针,正如我所说,它接受void*。。。我如何在下面的函数中使用此函数。。例如,如果我想将结构更改为:

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;
        }
    }
如果我有一个int结构,我可以用这个函数和一个int的复制函数,如下所示:

static void* copyInt(void* num){
    int* newInt=malloc(sizeof(*newInt));
    *newInt=*(int*)num;
    return newInt;
}
此外,我认为如果我更改并且不使用always struct node*会更好,我想要的可能是:typedef struct node\u t*node

concatLists(..., (copy_function)copyInt)

提供所有的“方法”(
cmp
CopyFunction
)作为参数变得很快。为什么不创建一个
列表
“对象”,它不仅包含指向头部和尾部的指针,还包含将列表泛化的“方法”

cmp
可能是一个比较函数(这意味着它应该包含两个参数),这意味着您可能正在尝试合并已排序的列表。好的,下面的代码使用一个通用列表实现来实现这一点。(我想我还是让
malloc
free
也可以插入为好。)


这看起来像是一个PS-表单
名称\u t
的类型被保留。@ikegami。。。根据POSIX,而不是C标准。
#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