今天看到一段代碼,覺得非常有意思。
void* say_hello(void* args) { cout << "Hello World!" << endl; return 0; }
這里的返回類型竟然是void*。一般來說如果沒有返回值,那么寫一個void就行了,void*到底是什么樣的存在?所以做了一些測試,總結了一些void*指針的用法。
1)void*可以指向任何類型的地址,但是帶類型的指針不能指向void*的地址
正常來說如果兩個指針類型不一樣的話,兩個指針變量是不可以直接相等的。例如int* a, float* b,假如令a = b,會直接發生編譯錯誤,而void*指針可以等於任何類型的指針。但是反過來不可以,也就是說一個有類型的指針不能指向一個void*類型的變量(哪怕此時void*變量已經指向了一個有類型的地址)。
float f = 5.5; float* pf = &f; void* pv = pf; float* pf2 = pv;//編譯錯誤,有類型的指針變量不能指向void*變量
2)void*指針只有強制類型轉換以后才可以正常取值
int main(int argc, const char * argv[]) { float f = 5.5; float* pf = &f; void* pv; pv = pf; //這句是可以的 cout<<*pv<<endl; //編譯錯誤,這樣直接對pv取值是錯誤的 cout<<*(float*)pv<<endl; //強制類型轉換后可以取值 return 0; }
在令pv = pf后,此時pv和pf指向的是同一個地址,值相同,但是兩者的類型是不一樣的。pf作為浮點型指針,是可以直接取到浮點數的,但是pv必須要強制類型轉換以后才可以取值,也就是說一個void*的指針必須要經過強制類型轉換以后才有意義。
int main(int argc, const char * argv[]) { float f = 5.5; float* pf = &f; void* pv; pv = pf; cout<<*(float*)pv<<endl; //強制類型轉換后可以取值,值為5.5 cout<<*(int*)pv<<endl; //強制類型轉換,值為1085276160 cout<<(int)(*(float*)pv)<<endl;//取值后再次類型轉換,值為5 return 0; }
如果把一個指向float*的值的void*指針,強制轉換成int*也是不對的。也就是說地址保存了什么樣的變量,就要轉化成哪種類型的指針,否則就會出錯。
3)void*指針變量和普通指針一樣可以通過等於0或者NULL來初始化,表示一個空指針
void* pv = 0; void* pv2 = NULL; cout<<pv <<endl; //值為0x0 cout<<pv2<<endl; //值為0x0
4) 當void*指針作為函數的輸入和輸出時,表示可以接受任意類型的輸入指針和輸出任意類型的指針
void* test(void* a) { return a; } int main() {
static int a = 5; int* pi = &a; cout<<pi<<endl; //值為0x100001060 cout<<test(pi)<<endl; //值為0x100001060 cout<<test((void*)pi)<<endl; //值為0x100001060 }
如果函數的輸入類型為void*,在調用時由於是值傳遞,所以函數實際接收到的應該就是一個地址值。這個值可以是任意類型。
int a = 5; int* pi = &a; void* test() { return pi; } int main() { cout<<test()<<endl; //值為0x100001060 }
輸出時同樣也是值傳遞,因此可以輸出任意類型指針指向的地址。
再讓我們回頭看初始的那段函數:
//返回了一個空指針 void* say_hello(void* args) { cout << "Hello World!" << endl; return 0; } //沒有返回值 void say_hello(void* args) { cout << "Hello World!" << endl; return; }
其實兩個函數實現的內容是一樣的。但是void*返回類型的函數返回了一個空指針,而void型沒有返回值。
總結:
1)void*類型的指針其實本質就是一個過渡型的指針狀態,必須要賦予類型(強制類型轉換)才能正常使用。
2)只能單向類型轉換。void*可以轉化成其他類型,但是有類型的不能轉化成void*。
2)在函數調用過程中的使用作為輸入輸出參數也非常好用,可以靈活使用任意類型的指針,避免只能使用固定類型的指針。