void
void最常見的用法,就是在函數中限定函數的參數和返回值的 void draw(void); 表明函數draw沒有參數也沒有返回值,void在別的的地方的應用我也沒見過;
實際上,如果把void 和int,char,double等類型放到一起理解的話,首先還是那句揭示本質的話:變量類型就是固定大小內存塊的別名,那么void占用多大內存呢,編譯器並沒有定義void占用多大內存,所以對於void var; 這樣的定義,編譯器自然是不允許的,在vs中的錯誤提示是:不允許使用不完整的類型。
void*
相比於void,void *就更加有意義一些。void *是一個指針類型,指針變量都占4byte內存(4byte=32 bit=2^32=4G,所以4byte就足以指向任何的內存地址了),所以對於void *p=NULL; 這樣的定義,編譯器可以為p分配內存,那么,如此定義的p有什么作用呢?
int *a=NULL;
p=a;
double *b=NULL;
p=b;
char c[16]={0};
p=c;
void* 就像一張白紙,任何類型的指針都可以直接賦值給void *類型的指針;
但是反過來
int *a=NULL;
a=p;//err
a=(int *)p;//需要強制類型轉換
這樣轉過來轉過去有何意義?
典型應用
一
void * memcpy(void *dest, const void *src, size_t len);
void * memset ( void * buffer, int c, size_t num );
memcpy和memset對外接收任何類型的指針,這樣是合理並且必要的,因為這是內存操作函數,是對bit進行操作的,考慮數據類型是沒有任何意義的(越觸及本質,越抽象,也越有包容性)。
二
int *a=NULL;
a=(int *)malloc(sizeof(int));
同樣的,malloc函數只關注你要多大的內存,你需要把它怎么划分是你的事情,但是你需要顯式的表明你是怎么划分的。這里語法要求是必須的,void *類型轉為其他類型必須強制類型轉換。
C語言中和C++中的異同
1、在C語言中,類型檢查不是很嚴格,因此可以將void*賦值給 type *。
//.c文件中
int a = 0;
int *ptr = &a;
void *ptr1 = ptr;
int *ptr2 = ptr1;//允許將void*類型賦值給int*,不會報錯
2、在C++中類型檢查比較嚴格,因此不允許將void*賦值給type *。
//.cpp文件中
int a = 0;
int *ptr = &a;
void *ptr1 = ptr;
int *ptr2 = ptr1;//不允許將void*類型賦值給int*,會報錯
int *ptr3 = (int*)ptr1;//需要強制類型轉換,才不會報錯
對於,返回void*的函數,如果要將返回值賦值給type *,需要進行類型轉換。