我有一个这样定义的类型:
struct DynTab_s {
int object_count;
//other fields
void *data;
};
typedef struct DynTab_s *Dyntab_t; //note that type I use is pointer to struct
我有一个存储实用程序,我可以用来存储和检索它们。我选择支持int,double和指针类型。我有一个函数来通过键检索int和double值:
int MyHashtableGet(MyHashtable_t Hashtable, void *Key, void *Value)
{
void *Row = NULL;
int RetValue = -1;
MakeRow(Hashtable, Key, NULL, &Row);
if (!MyStoreSelect(Hashtable->TableId, Row))
{
switch (Hashtable->ValueType)
{
case MY_HASHTABLE_TYPE_INT:
*(int *)Value = *(int *)((char *)Row + Hashtable->KeySize);
break;
case MY_HASHTABLE_TYPE_POINTER:
//after row below I can see the DynTab_t in the item when I cast it
Value = *(void **)*(int **)((char *)Row + Hashtable->KeySize);
break;
}
}
MyFree(Row);
return RetValue;
}
为int工作。但是当我试图获得Dyntab_t时,不是指针。如果我使用函数
,这是有效的void *MyHashtableGetPointer(MyHashtable_t Hashtable, void *Key)
{
void *Row = NULL;
void *RetValue = NULL;
MakeRow(Hashtable, Key, NULL, &Row);
if (!MyStoreSelect(Hashtable->TableId, Row))
RetValue = *(void **)*(int **)((char *)Row + Hashtable->KeySize);
MyFree(Row);
return RetValue;
}
当我打电话给:
int Key = 1;
DynTab_t MyTab;
MyTab = (DynTab_t)MyHashtableGetPointer(MyHashtable, &Key);
问题是我可以使用此MyHashtableGet来获取DynTab_t项目,还是第二个参数必须为void **类型?如果是,请在MY_HASHTABLE_TYPE_POINTER的情况下提供确切的语法和MyHashtableGet。
谢谢& BR -Matti
答案 0 :(得分:1)
问题是我可以使用此MyHashtableGet来获取DynTab_t项目,还是第二个参数必须为void **类型?
唯一的区别(如果您存储指针,就像存储int
值一样),那就是在检索int
时,您会传递int
的地址变量;并且在检索指针时,您将传递指针变量的地址。 void *
可以保存任何地址(有时除了函数) - 包括其他指针。所以最后一个参数可以正常为void *
,只要你在其他地方适当地处理它。
int
相同的方式存储指针,那么在相同的间接级别,您将获得整数类型的int
和void *
对于指针类型,那么为什么它们被解引用到不同的级别?
case MY_HASHTABLE_TYPE_INT:
*(int *)Value = *(int *)((char *)Row + Hashtable->KeySize);
break;
在上面,似乎((char *)Row + Hashtable->KeySize)
可以获得指向您存储的任何值的指针,尽管指针类型错误。然后,(int *)
会转换为数据类型的指针(在本例中为int
),然后取消引用并指定Value
指向的内容。
case MY_HASHTABLE_TYPE_POINTER:
Value = *(void **)*(int **)((char *)Row + Hashtable->KeySize);
break;
但是在这里,你转向int **
,取消引用,转为void **
,然后重新引用,然后分配到Value
而不是Value
点?是不是有太多的解构?你不应该分配到Value
而不是Value
的目标吗?为什么你需要投射到int **
?我认为应该更像这样:
case MY_HASHTABLE_TYPE_POINTER:
*(void **)Value = *(void **)((char *)Row + Hashtable->KeySize);
break;
然后,在调用时得到一个int:
...
int Val;
MyHashtableGet(Table, Key, &Val);
...并在调用时获取指针:
...
void *Val;
MyHashtableGet(Table, Key, &Val);
修改强>
这假定了以下两种情况之一:您传递Value
地址的变量是void *
,或者您传递地址的变量是内部表示相同的类型作为void *
的方式(通常是真的,但不保证)。如果你想依赖于在赋值时转换的指针类型(如果它们的表示不同),你可以将MyHashtableGetPointer()
函数实现为MyHashtableGet()
的包装:
void *MyHashtableGetPointer(MyHashtable_t Hashtable, void *Key)
{
void *res = NULL;
MyHashtableGet(Hashtable, Key, &res);
return res;
}
答案 1 :(得分:0)
这实际上取决于你想怎么做。您可以使用引用(仅在C ++中)或指针(C和C ++)来执行此操作:
void changeTheParamRef(struct myStruct &s)
{
myStruct other;
s = other; // or
s.something = other.something;
}
void changeTheParamPtr(struct myStruct *s)
{
myStruct other;
*s = other; // or
s->something = other.something;
}
void allocStruct(struct myStruct **s)
{
*s = malloc(sizeof(myStruct));
}
除非您想要返回或更改指针而不是值,否则不需要指向指针的指针。
调用以上样本:
myStruct s;
changeTheParamRef(s);
changeTheParamPtr(&s);
myStruct *p;
allocStruct(&p);
changeTheParamRef(*p);
changeTheParamPtr(p);