最近在看執行緒池的實現,pthread的函式裡面大量出現了 諸如 void *arg等無型別指標,經過多方查閱資料,談談自己的理解。
void的字面意思是「無型別」,void *則為「無型別指標」,void *可以指向任何型別的資料。(關鍵)
void指標指向的資料型別未定,將其值賦給其他值時要型別轉換,但是任何型別的指標都可以直接賦值給void*,無需進行強制型別轉換:;比如:
void *arg;
int i;
i=(int *)arg;
任何型別的指標都可以直接賦值給void*,無需進行強制型別轉換:
void *p1;
int *p2;
p1 = p2;
假如定義void型別:
void a;
這行語句編譯時會出錯,即使void a的編譯不會出錯,它也沒有任何實際意義。
void的出現只是為了一種抽象的需要,如果你正確地理解了物件導向中「抽象基類」的概念,也很容易理解void資料型別。正如不能給抽象基類定義乙個例項,我們也不能定義乙個void變數。
void關鍵字的使用規則:
1. 如果函式沒有返回值,那麼應宣告為void型別;
2. 如果函式無引數,那麼應宣告其引數為void;
3. 如果函式的引數可以是任意型別指標,那麼應宣告其引數為void * ;
4. void不能代表乙個真實的變數;
下面詳細解釋:
void真正發揮的作用在於:
(1)對函式返回的限定;
(2)對函式引數的限定。
1.如果函式沒有返回值,那麼應宣告為void型別;
在c語言中,
凡不加返回值型別限定的函式,就會被編譯器作為返回整型值處理。但是許多程式設計師卻誤以為其為void型別
。例如:
add ( int a, int b )
//返回的是int型別
當然我們在編寫c/c++程式時,對於任何函式都必須乙個不漏地指定其型別。如果函式沒有返回值,一定要宣告為void類
型。這既是程式良好可讀性的需要,也是程式設計規範性的要求。
2.小心使用void指標型別
按照ansi(american national standards institute)標準,不能對void指標進行演算法操作,即下列操作都是不合法的:
void * pvoid;
pvoid++; //ansi:錯誤
pvoid += 1; //ansi:錯誤
//ansi標準之所以這樣認定,是因為它堅持:進行演算法操作的指標必須是確定知道其指向資料型別大小的。
//例如:
int *pint;
pint++; //ansi:正確
gnu則不這麼認定,它指定void *的演算法操作與char *一致。
因此下列語句在gnu編譯器中皆正確:
pvoid++; //gnu:正確
pvoid += 1; //gnu:正確
3.如果函式的引數可以是任意型別指標,那麼應宣告其引數為void *
比如刷acm題目的時候經常用到的memset函式,看了他的原型 = =覺得自己low爆了,原來一直在用void*
void * memset ( void * buffer, int c, size_t num );
還有 void * memcpy(void *dest, const void *src, size_t len);
這樣,任何型別的指標都可以傳入memcpy和memset中,這也真實地體現了記憶體操作函式的意義,因為它操作的物件僅僅是一片記憶體,而不論這片記憶體是什麼型別。同時返回的也是void *型別;
我相信看了這個函式原型,對void*就會有直觀的理解了。
主要參考:
void及void指標型別
1.概述 許多初學者對c c 語言中的void及void指標型別不甚理解,因此在使用上出現了一些錯誤。本文將對void關鍵字的深刻含義進行解說,並 詳述void及void指標型別的使用方法與技巧。2.void的含義 void的字面意思是 無型別 void 則為 無型別指標 void 可以指向任何型別...
void指標 void 的用法
指標有兩個屬性 指向變數 物件的位址和長度 但是指標只儲存位址,長度則取決於指標的型別 編譯器根據指標的型別從指標指向的位址向後定址 指標型別不同則定址範圍也不同,比如 int 從指定位址向後尋找4位元組作為變數的儲存單元 double 從指定位址向後尋找8位元組作為變數的儲存單元 1.void指標...
void型別及void指標
基於前面的一篇部落格模擬實現 memcpy 和 memmove 時用到的void 指標展開關於 void 和 void 指標的概述 1.void 相信大家不會陌生,經常定義無返回值的函式是用 void 定義,表示函式無需返回值 void fun void 2.void 的字面意思是 無型別 void...