你应该给你的结构命名。例如,
struct foo {
char * str1;
float tt1;
};
然后你可以像这样声明你的实例:
struct foo var1 = { "This is me", 12 };
然后你可以在你的函数中强制void *
转换为 a :struct foo *
void printStruct(void * ptr) {
printf("str=%s\n", ((struct foo *)ptr)->str1);
}
你可以这样称呼它:
int main(...) {
struct foo var1 = { "This is me", 12 };
printStruct(&var1);
}
更新:评论者约翰内斯是正确的,我的回答并没有说明原发帖人说他可能不知道每个结构的类型。更新的解决方案如下:
由于您知道所有结构都包含 a char * str1
,因此您可以通过将结构直接转换为仅包含 的通用标记结构来利用 C 的“平面内存模型” char * str1
。这仅适用于 structschar * str1
的第一个元素。
struct base { char * str1; };
struct { char * str1; float tt1; } var1 = { "This is me", 12 };
struct { char * str1, int tt2; } var2 = { "This is me", 18 };
void printStruct(void * ptr) {
printf("str is %s\n", ((struct base *)ptr)->str1);
}
不过,这是一个非常肮脏的黑客攻击,IMO。如果您要共享其他成员,您将无法使用相同的技巧。
另一种选择是定义一个struct
使用带有枚举数的联合来跟踪联合中实际使用的类型:
enum { FLOAT_TYPE, INT_TYPE };
struct foo {
char * str1;
union {
float tt1;
int tt2;
} numericValue;
int unionType;
};
这将允许您定义如下变量:
struct foo var1 = { .str1 = "This is me", .numericValue.tt1 =12, .unionType = FLOAT_TYPE };
struct foo var2 = { .str1 = "This is me", .numericValue.tt2 =18, .unionType = INT_TYPE };
然后你不需要处理不同类型的结构,你可以将你的 void 指针转换为struct foo *
:
void printStruct(void * ptr) {
struct foo * p = (struct foo *)ptr;
printf("string is %s\n", p->str1);
}
这可能需要更多的工作,但它更清洁,IMO。