void *vp;
void*是一種特別的指針,因爲它沒有指向的類型,或者說不能根據這個類型判斷出指向對象的長度。
void *指針具有以下特點:
1、任何指針(包括函數指針)都可以賦值給void指針;
type *p;
vp=p; //不需轉換,只獲得變量/對象地址而不獲得大小
2. void指針賦值給其他類型的指針時都要進行轉換;
type * p=(type *)vp; //轉換類型也就是獲得指向變量/對象大小
3. void指針在強制轉換成具體類型前,不能解引用;
*vp //錯誤 (因爲void指針只知道指向變量/對象的起始地址,而不知道指向變量/對象的大小(佔幾個字節)所以無法正確引用 )
4. void指針不能參與指針運算,除非進行轉換。
(type*)vp++; //等價於:vp=vp+sizeof(type)
void*的作用
1、傳參:通用類型
可以作爲函數模板,鏈表等參數的通用參數。在使用時,只需要強制類型轉換就可以。
例如內存操作函數memcpy和memset的函數原型分別爲:
void* memcpy(void *dest, constvoid *src, size_t len);
void* memset(void *buffer, int c, size_t num);
這樣,任何類型的指針都可以傳入memcpy和memset中,這也真實地體現了內存操作函數的意義,
因爲它操作的對象僅僅是一片內存,而不論這片內存是什麼類型。
2、強制類型轉換
有時候由於重載等的干擾,導致需要轉換成void *,來進行取地址。
例如,(void *)obj.member,就可以取到member的地址;直接&(obj.member)取到的實際上是obj的開始地址。
3、指向0的地址
(void *)0,指向全是0的地址,相當於NULL。
簡單的小例子:
#include <stdio.h>
int main(){
void *data = "Hello World";//一個無類型指針代替所有的類型,這裏是存儲字符型數據
printf("%s\n",data);//將其輸出
return 0;
}
下面是無類型指針,訪問是一個字節一個字節的訪問的。
#include <stdio.h>
#include <stdlib.h>
int main(){
void *data = malloc(8);//一個無類型指針代替所有的類型
printf("%ld\n",sizeof(data[0]));//沒有創建具體的數據類型,訪問的時候是一個字節一個字節訪問的。
free(data);//記得釋放內存
return 0;
}
輸出
1
下面創建一個整型數據類型,在訪問時將輸出4,即整型的數據長度來訪問。
#include <stdio.h>
#include <stdlib.h>
int main(){
void *data = malloc(8);//一個無類型指針代替所有的類型
int *intData = data;//爲其指定一個整型的數據類型
printf("%ld\n",sizeof(intData[0]));//輸出其數據尺寸
free(data);//記得釋放內存
return 0;
}
輸出
4
空指針並賦值
#include <stdio.h>
#include <stdlib.h>
int main(){
void *data = malloc(8);//一個無類型指針代替所有的類型
int *intData = data;//爲其指定數據類型
intData[0] = 10000;
printf("%d\n",intData[0]);//輸出其值
free(data);//記得釋放內存
return 0;
}
輸出
10000