我在C中实现了一个通用的双向链表,我编写了前向和后向遍历的函数。在这些函数中,我想打印列表中包含的数据,但由于它是通用的,我很难弄清楚如何做到这一点。显然,我不能printf
使用%d
或其他东西,因为列表可能包含任何数据类型。任何以不同方式处理这种问题的建议都会受到赞赏,因为我已经考虑了很长一段时间而且我很茫然。谢谢!
答案 0 :(得分:4)
你可以做很多事情。
例如,您可以将不仅包含void *
的结构存储到元素的数据中,还可以存储可能的数据类型的指示,甚至只存储{{1}所需的格式字符串对象。
您还可以考虑一个包含printf
数据的结构,以及一个允许您将数据转换为字符串的函数指针。这基本上是在C语言中最低限度地模仿C ++的多态性。
编辑:正如Wickstopher指出的那样,你只是没有得到编译时类型的安全性。弄乱功能指针,你将有一个不合适的功能处理你的数据,可能导致你的程序出现段错误,碾过你的小猫,烧毁你的公寓,与你最小的孩子一起逃跑或在厨房里冒烟
答案 1 :(得分:2)
您需要为节点声明的struct
中的标记字段。为数据类型定义enum
为
enum {INT_TYPE, FLOAT_TYPE, DOUBLE_TYPE, CHAR_TYPE} type;
对于每种数据类型,您需要为type
分配相应的枚举常量。在打印功能中,您必须检查type
的值,然后使用适当的说明符。
答案 2 :(得分:1)
C不支持任何类型的运行时类型检查,因此这是不可能的。见runtime determine type for C(类似问题)。
如果要支持有限范围的数据类型,可以考虑在节点结构中添加枚举,但这不会为您提供真正的通用功能,并且在编译时不会强制执行。
答案 3 :(得分:1)
假设您的节点有一个指向节点内容的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);
}