[英]Can I get a pointer to a struct as a parameter from a function in C?
我有一个这样定义的类型:
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-马蒂
问题是我可以完全使用此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;
}
这实际上取决于您要如何做。 您可以使用引用(仅在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);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.