2017-06-14 124 views
0

我不得不爲不同的數據類型使用相同的函數來避免額外的函數和冗長的代碼。 我在函數中使用(void *)參數,並且希望檢索與main發送的數據類型相同的數據類型。即如果int來自main,我應該能夠從void * of「func」中猜測int數據類型。這裏的樣本函數......當c中的不同輸入數據類型使用相同的函數時,是否可以在調用的函數中取回參數的數據類型?

void func(void* input) 
{ 
    if(input is int) 
     printf("%d", input); 
    else if (input is char) 
     printf("%c", input); 
    else if (input is struct) 
     //do somthing; 
    } 

和主要是:

int main() 
{ 
    int q=1; 
    char w='c'; 
    func(&q); 
    func(&w); 
    func(&struct); 
    return 0; 
} 
+5

「否」。常用的方法是傳遞'tagged struct/union'(或者依賴其他上下文數據,如fscanf)。 – user2864740

+1

@ user2864740:雖然你可以在C11中使用包裝宏來模擬它, '#define func(p)(printf(_Generic(*(p),int:「%d」,char:「%c」),(p)))'。 – doynax

回答

1

當被宣佈爲函數的參數爲​​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); 
} 
相關問題