假设一个函数将void指针作为参数,如下所示:int func(void *p);
我们如何确定或猜测p指向的类型?
答案 0 :(得分:23)
一般情况下,你不能。在某些情况下,如果对p指向的内容有保证,您可以查看该地址及其后的内容以查找。一般来说,你的函数应该知道传递的是什么,除非它只是传递它。
C中的数据和函数参数只是一堆混合在一起的。除非你使用其中一些位来告诉你这些位是什么,否则没有一致的方法来识别它。
答案 1 :(得分:6)
答案 2 :(得分:6)
当然可以,而且也很容易。它是C,做你想做的任何事,你想要它。
制作一个类型系统。将你传递的所有内容放入一个结构中,使第一个或第二个字节成为一个幻数,以确定结构中包含的超出幻数的内容。
创建一些函数来创建/获取/设置/销毁“类型变量”。
创建一些其他函数以在运行时添加和注册新类型。
创建一些定义,以便更容易阅读和类型化结构。
在您了解它之前,您将拥有一个可以用于您的项目的好的专有类型系统,并且它将始终完全按照您的要求完成您想要和需要的。
你可能会疯狂并将其发展成一个完全面向系统的对象。或者保存自己的工作,并使用已经疯狂的所有其他人的工作 - http://en.wikipedia.org/wiki/GObject
答案 3 :(得分:0)
我遇到了类似的问题,我发现自己不得不为编程语言项目编写指令集。我遇到了这个问题因为我有一个函数指针数组,所以可以枚举函数并在for循环中运行(用于在线帮助和语法等)。例如:
struct List_Str *(*InstructionSet[])(struct List_Str *ContextPrefix,struct List_Str *ContextSuffix)=
{
AAVF,Add,AddEmotions,AddEmoDebug,AddScope,...
};
现在您可以使用char *而不是struct List_Str *类型轻松地执行相同的操作,然后使用snprintf和atoi以及其他转换函数将所有数据转换为字符串格式。如果您这样做:
man isalpha
这显示了ctype.h中的许多函数,可以为您提供如何确定字符串中保存的数据类型的想法。
将所有类型折叠成“stringy”格式允许极大的灵活性和规律性,但是自动将数据从字符串转换为整数,浮点数等是非常艰巨的,但是一旦例程被冻结,就会很有成效。
如果你打算保存二进制数据,那么就不能使用字符串,因为0个字符可以在二进制数据中,这会使strlen函数混淆。此外,您不知道malloc离开作用域后的长度,因此在char *的前几个字节中建议在数据之前存储取消引用数据的长度。
最后一件事,我不建议将数据存储在void *中,它太模糊了。我建议使用char *,因为它更具体一些,可以包含void * can的所有内容,如果有什么看起来很可疑,编译器会事先通知你。