C中的通用编程

col*_*ass 8 c generics printf generic-programming void-pointers

我正在用纯C编写通用链表实现.

struct Node {
    void *value;
    struct Node *next;
};

struct LinkedList {
    struct Node *start;
    struct Node *end;
};

void LinkedList_new(struct LinkedList* llist) {
    llist->start = 0;
    llist->end = 0;
    return;
}

void addNode( struct LinkedList *ll, void *_value ) {
    if ( NULL == ll->start ) {
        ll->start = (struct Node *) malloc( sizeof(struct Node) );
        ll->end = ll->start;
    } else {
        ll->end->next = (struct Node *) malloc( sizeof(struct Node) );
        ll->end = ll->end->next;
    }
    ll->end->value = _value;
    return;
};
Run Code Online (Sandbox Code Playgroud)

一切都很好.我的问题是当我将值打印到屏幕上时.我似乎无法找到打印的通用实现.

有没有办法确定分配给的TYPE void *?(然后使用switch语句进行转换)

void printFunc(int aInt) {
    char str[15];
    sprintf(str, "%d", aInt);
    printf(str);
}
Run Code Online (Sandbox Code Playgroud)

这是一个适用于int的实现.最糟糕的情况我正在考虑为每个TYPE编写不同的函数.这真的是我使用时的唯一途径void *吗?

有一个更好的方法吗?

unw*_*ind 16

不,没有办法从指针中找出答案.这需要将类型信息存储在所有运行时结构中某个明确定义的位置,这根本不是C使用机器的方式.

常见的解决方案是数据类型的用户提供应用程序所需的打印功能,因为应用程序知道所存储的数据类型.也就是说,通常有一个迭代函数,它接受一个函数指针,在列表的每个元素上调用用户的函数(可能会打印元素).

以下是这样一个函数的外观:

void LinkedList_foreach(const LinkedList *start,
                        bool (*func)(void *element, void *data), void *data);
Run Code Online (Sandbox Code Playgroud)

上面应该调用func()列表的每个元素,传递元素的数据附加的用户提供的data指针,调用者可以使用它来维护遍历的状态.回调func()应该返回false以停止迭代,true继续前进.

要打印整数,假设整数存储在指针中,您可以:

static bool print_int(void *element, void *data)
{
  printf("%d\n", (int) element);
  return true;
}
Run Code Online (Sandbox Code Playgroud)

另外,请不要malloc()在C中转换返回值.