打印包含 void* 的链表元素

Printing elements of a linked list containing void*

我正在用 C 语言实现一个通用的双向链表,并且我已经编写了用于向前和向后遍历的函数。在这些函数中,我想打印列表中包含的数据,但由于它是通用的,所以我很难弄清楚如何做到这一点。显然我不能只 printf 使用 %d 或其他东西,因为列表可以包含任何数据类型。任何以不同方式处理此问题的建议将不胜感激,因为我已经考虑了很长一段时间而且我不知所措。谢谢!

您在为节点声明的 struct 中需要一个标记字段。为数据类型定义一个 enum 作为

enum {INT_TYPE, FLOAT_TYPE, DOUBLE_TYPE, CHAR_TYPE} type;

对于每种数据类型,您需要为 type 分配相应的枚举常量。在打印功能中,您必须检查 type 的值,然后使用适当的说明符。

你可以做很多事情。

例如,您可以存储的结构不仅包含元素数据的 void *,而且还指示可能的数据类型,甚至只是 printf 所需的格式字符串object.

您还可以想到一个包含数据的 void * 的结构,以及一个允许您将数据转换为字符串的函数指针。这基本上是在 C 中最低限度地模拟 C++ 的多态性。

编辑: 正如 wickstopher 指出的那样,你只是没有得到 compile-time 类型安全。弄乱函数指针,你将有一个不合适的函数处理你的数据,可能导致你的程序出现段错误,运行 超过你的小猫,烧毁你的公寓,运行 带走你最小的 child 或者在你的厨房抽烟。

C 不支持任何类型的运行时类型检查,因此这是不可能的。参见 runtime determine type for C(类似问题)。

如果您想支持有限范围的数据类型,您可以考虑向您的节点结构添加一个枚举,但这不会让您获得真正的通用功能,并且在编译时无法强制执行。

假设你的节点有一个指向节点内容的void *指针,在指向列表中下一个和前一个元素的指针中,提供一个打印节点的函数,例如

void PrintNode (Node_t *node, void (*fprint)(void *));

这个函数会获取节点的元素,然后调用用户提供的函数来实际打印节点的内容。

typedef struct stNode {
  void *NodeContents;
  struct stNode *prev;
  struct stNode *next;
} Node_t;

void PrintNode (Node_t *node, void (*print)(void *))
{
  if (node && node->NodeContents && print)
    print(node->NodeContents);
}