2012-07-24 87 views
84

今天當我讀別人的代碼時,我看到類似void *func(void* i);的東西,這個void*分別代表函數名和變量類型是什麼意思?void *意味着什麼以及如何使用它?

另外,我們什麼時候需要使用這種指針以及如何使用它?

+2

你在用什麼C書?你在要求整個章節的更好的部分。 – cnicutar 2012-07-24 08:16:03

+1

看看http://stackoverflow.com/questions/692564/concept-of-void-pointer-in-c-programming – WDan 2012-07-24 08:21:00

+0

它的回答之前:http://stackoverflow.com/questions/1043034/what-does -void-mean-in-cc-and-c and here: http://stackoverflow.com/questions/7324860/using-void-in-c – d33pika 2012-07-24 08:21:17

回答

110

一個指向void是一個 「通用」 指針類型。 A void *可以轉換爲任何其他指針類型而無需顯式強制轉換。你不能取消引用void *或做指針運算;您必須首先將其轉換爲指向完整數據類型的指針。

它用於需要能夠在同一代碼中使用不同指針類型的地方。一種常用列舉的例子是庫函數qsort

void qsort(void *base, size_t nmemb, size_t size, 
      int (*compar)(const void *, const void *)); 

base是一個數組的地址,nmemb是陣列中元件的數量,size是各元件的尺寸,並且compar是一個指向函數來比較數組中的兩個元素。它被稱爲像這樣:

int iArr[10]; 
double dArr[30]; 
long lArr[50]; 
... 
qsort(iArr, sizeof iArr/sizeof iArr[0], sizeof iArr[0], compareInt); 
qsort(dArr, sizeof dArr/sizeof dArr[0], sizeof dArr[0], compareDouble); 
qsort(lArr, sizeof lArr/sizeof lArr[0], sizeof lArr[0], compareLong); 

陣列表達式iArrdArr,並lArr被隱式地從數組類型轉換爲指針類型的函數調用,並且每個被隱式地從「指針轉換爲int/double/long 「到」指向void的指針「。

比較功能將類似於:

int compareInt(const void *lhs, const void *rhs) 
{ 
    const int *x = lhs; // convert void * to int * by assignment 
    const int *y = rhs; 

    if (*x > *y) return 1; 
    if (*x == *y) return 0; 
    return -1; 
} 

通過接受void *qsort可以與任何類型的數組。

使用void *的缺點是您將類型安全性置於窗外並轉向迎面而來的交通。沒有什麼來保護你使用了錯誤的比較例程是:

qsort(dArr, sizeof dArr/sizeof dArr[0], sizeof dArr[0], compareInt); 

compareInt期待它的參數是指向int S,但實際上是與double s工作。編譯時無法解決這個問題;你只會結束一個錯誤排序的數組。

+3

實際上不能保證'void *'可以被轉換爲函數指針。但對於數據指針而言,你所說的是成立的。 – Vatine 2016-07-12 10:52:40

2
void* 

是'指向內存的指針,沒有假設存儲了哪種類型'。 可以使用,例如,如果你想傳遞一個參數來運作,這種說法有幾種類型和功能,您將處理每種類型。

-5

之前函數名的空白意味着它不返回任何東西。只是做一些東西。另一方面VOID作爲參數使它成爲通用函數,可以接受任何類型的參數。但是你必須提供這個參數的大小。

+2

'void'和'void *'之間有區別。查看其他答案 – Aftnix 2012-07-24 08:24:05

0

該函數接受一個指向任意類型的指針並返回一個。

2

你可以看看這篇關於指針http://www.cplusplus.com/doc/tutorial/pointers/的文章,並閱讀章節:void pointers

這也適用於C語言。

void類型的指針是一種特殊類型的指針。在C++中,void 表示缺少類型,所以void指針指向的是 指向沒有類型(因此也有未確定的長度和未確定的取消引用屬性)的值。

這允許void指針指向任何數據類型,從整數 值或float到字符串。但作爲交換,他們有一個很大的限制:它們指向的數據不能直接取消引用(這是合乎邏輯的,因爲我們沒有類型來取消引用 ),因此我們將始終必須在 空隙指針指向一個具體 數據類型解引用它之前的一些其他指針類型。

17

使用void *表示該函數可以接受一個不需要是特定類型的指針。 例如,在插座的功能,你必須

send(void * pData, int nLength) 

這意味着你可以把它在很多方面,例如

char * data = "blah"; 
send(data, strlen(data)); 

POINT p; 
p.x = 1; 
p.y = 2; 
send(&p, sizeof(POINT)); 
+0

這與其他語言的泛型非常相似,但沒有類型檢查,對吧? – 2016-08-25 14:05:06

+3

我想它會是相似的,但是因爲沒有類型檢查,犯錯可能會導致非常奇怪的結果或導致程序徹底崩潰。 – TheSteve 2016-08-28 23:58:37

1

一個void*是一個指針,但它指向的類型是未指定的。當你將一個void指針傳遞給一個函數時,你需要知道它的類型是什麼,才能在函數中稍後將它轉換回正確的類型來使用它。您將在pthreads中看到示例,該示例使用的函數與您的示例中用作線程函數的原型完全相同。然後,您可以使用void*參數作爲指針到您選擇的一個通用的數據類型,然後將它轉換回該類型的線程函數中使用。在使用void指針時需要小心,因爲除非你回到它的真正類型的指針,否則你可能會遇到各種各樣的問題。

1

C11標準(n1570)§6.2.2.3AL1 P55表示:

一個指向void可轉化爲或者從一個指針到任何對象 類型。指向任何對象類型的指針都可以被轉換爲指向void的指針並返回;結果應與原始指針 相等。

你可以使用這個通用指針來存儲指向任何對象類型的指針,但是你不能對它使用通常的算術運算,而且你不能遵守它。

2

C是在這方面顯着。可以說 虛空就是虛無 void *就是一切(可以是everyhing)

它只是這個微小的*而已。

雷內指出了。 void *是指向某個位置的指針。什麼是如何「解釋」是留給用戶的。

這是在C中使用不透明類型的唯一方法。非常突出的例子可以在例如glib或通用數據結構庫中找到。在「C接口和實現」中對它進行了非常詳細的處理。

我建議你閱讀完整章節,並嘗試理解指向「獲取它」的概念。

2

void指針被稱爲泛型指針。我想用一個示例pthread場景來解釋。

線程函數將有原型

void *(*start_routine)(void*) 

的並行線程API設計者考慮的參數和返回線程函數的值。如果這些東西是通用的,我們可以在作爲參數發送時將類型轉換爲void *。同樣的返回值可以從void *中檢索(但是我從來沒有使用線程函數的返回值)。

void *PrintHello(void *threadid) 
{ 
    long tid; 

    // ***Arg sent in main is retrieved *** 
    tid = (long)threadid; 
    printf("Hello World! It's me, thread #%ld!\n", tid); 
    pthread_exit(NULL); 
} 

int main (int argc, char *argv[]) 
{ 
    pthread_t threads[NUM_THREADS]; 
    int rc; 
    long t; 
    for(t=0; t<NUM_THREADS; t++){ 
     //*** t will be type cast to void* and send as argument. 
     rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t); 
     if (rc){ 
     printf("ERROR; return code from pthread_create() is %d\n", rc); 
     exit(-1); 
     } 
    }  
    /* Last thing that main() should do */ 
    pthread_exit(NULL); 
} 
相關問題