void的字面意思是空類型,void *的意思是空類型指針,void 不是一個真正的類型,我們在聲明變量的時候從來不會像下面這樣聲明:
void a;
如果我們寫了一行這樣的代碼,某些編譯器會直接報錯,有些則不會,但也沒有任何意義。
void真正的用途在下面兩個方面:
-
對函數返回值的限定
-
對函數參數的限定
比如,函數沒有返回值,那麼函數可能會聲明成這樣:void fun(int a);
如果函數有返回值,但是函數沒有參數,那麼函數的可能會聲明成這樣:int fun(void)。
以上的情況都是很好理解的。下面介紹void *的一些用法。
1. 函數可接受任意類型的指針。
用過memset或者memcpy的細心的人會發現,在gcc中編譯類似下面的代碼都不會有警告:
int a;
int *p = &a;
memset(p, 0, 4);
或者
char c[4];
char *p = c;
memset(p, 0, 4);
爲什麼memset傳int *還是char *都沒有問題呢?我們知道不同類型間複製是要進行強制轉換的,那麼這裏爲什麼不用強制類型轉換呢。我們看memset的原型會發現,memset的第一個參數就是void *。
2. void *類型可以接受任意類型指針。
例如:
void *p1;
char *p2 = "hellp";
p1 = p2;
這是沒有問題的,任何類型的指針都可以直接賦值給它,無需進行強制類型轉換。但需要注意的一點是,void *的類型並不能無需類型轉換直接賦值給其他類型,比如malloc的返回值是void *,那麼我們一般這樣寫:char *p = (char *)malloc(4);
3. void *類型不能做運算
比如我們不要做類似這樣的操作:
void *p;
p++;
說白了void並不是一個真實的變量,void可以看作一個抽象概念。
以上說法由於C標準不同,可能有部分差異,需要特殊對待,但大體就是這樣的。