當被宣佈爲函數的參數爲void *
那麼任何類型的信息是不可用的功能。 C不提供檢查void *
變量的方法來確定它的實際類型。
這意味着,當一個函數(如您使用void *
參數描述的參數)與多個類型一起使用時,參數必須包含某種類型的註釋或指示。
一個標準方法是使用一個struct
,其中包含一個類型指示符,後跟所有支持的各種類型的union
。
typedef struct {
unsigned short usType;
union {
int iValue;
float fValue;
} U;
} MyVoidType;
的另一種方式是使用一個void *
參數用於待由函數與表示所述類型的第二參數進行處理的東西。
func(void *pItem, unsigned short usType)
{
switch (usType) {
case 1:
{
ItemType1 *pItem1 = pItem;
// do things with pItem1
}
break;
// other cases for other types
}
}
這與使用varargs
可變參數功能時可能遇到的問題類似。通過varargs
,編譯器知道還有其他參數,但是不檢查它們的類型,因爲其他參數的類型信息不是函數定義/聲明的一部分。輸出函數的printf()
系列使用格式說明符來解決此問題,函數用於確定參數類型以及如何格式化該值以打印參數。
該方法存在問題,因爲需要使用實際數據項來維護註釋或指示,並確保在switch
語句中的適當更改支持任何新類型。它也最終導致編譯現在無法爲您進行參數檢查的問題。
所以我也做了類似下面的事情。在一個文件中,我有一個處理所有我想處理的各種類型的函數。然後這個函數被封裝在多個版本中,並帶有適當的類型化參數,這些參數只不過是用適當的註釋來調用單個函數。
static short funcmain(void *pItem, unsigned short usType)
{
switch (usType) {
case 1:
{
ItemType1 *pItem1 = pItem;
// do things with pItem1
}
break;
// other case statements
}
}
short funcType1 (ItemType1 *pItem)
{
return funcmain (pItem, 1);
}
short funcType2 (ItemType2 *pItem)
{
return funcmain (pItem, 2);
}
「否」。常用的方法是傳遞'tagged struct/union'(或者依賴其他上下文數據,如fscanf)。 – user2864740
@ user2864740:雖然你可以在C11中使用包裝宏來模擬它, '#define func(p)(printf(_Generic(*(p),int:「%d」,char:「%c」),(p)))'。 – doynax