[英]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.