今天,有個師弟問我:「師兄,空指針和void *類型指針是怎樣的?」函數
當時,我大概的說法是:指針
一、空指針是沒有指向的指針,將暫時用不到的指針定義成空指針,能防止誤用。內存
二、而void * 類型的指針是有指向的指針,但它的指向的數據的類型暫時不肯定,因此先弄成void * 類型,後期通常要強制轉換的。get
回來後,發現這種說法雖然勉強可以接受,但依然有不足的地方,如今補充更正一下:io
一、空指針實質上是有指向的指針,但它指向的地址是很小的地址,約定俗成爲地址0,我來解釋一下爲何。編譯
#include <stdio.h>
void main(){
int * str = NULL;
gets(str);
printf("%s",str);
}
這個程序在語法上是沒有問題的,可是咱們編譯、連接都沒有報錯,可是咱們打開的時候卻出錯了。
緣由是空指針指向的地址是不保存數據,同時不容許程序訪問的。數據類型
那麼,這個NULL究竟是什麼呢?語法
我打開了用F12對着NULL 單擊打開,看看它究竟是什麼,結果打開了頭文件stdio.h,顯示 #define NULL ((void *)0) 程序
顯然,這是一個宏定義。NULL 其實是((void*)0) ,容易看出,外層的括號純粹是爲了防止歧義;裏層的括號則是強制類型轉換,轉換成void * 類型,原本void * 類型是用來存放地址的,那麼這裏的0天然就是地址0了。數據
在內存分配方面,較小的地址是不用來存放數據的,也不容許程序訪問的。因此,指針指向了它,就是這個指針不能操做它指向的這塊較小的地址。
哈哈,至此,空指針算是解釋通了。
簡單來講,空指針有指向,可是它指向的地址是特殊的,該地址不容許存放數據和不容許程序訪問,因此空指針不能操做該地址裏的東西,咱們就理解爲「指針指向了空,沒法操做了」。
二、void * 類型指針,這個類型指針指向了實實在在的存放數據的地址,可是該地址存放的數據的數據類型咱們暫時不知道。
舉個例子,咱們的動態內存分配就是這樣,一開始只是分配地址,但沒有知道這塊地址用了存放什麼,接着強制類型轉換,使得它用來存放咱們想要存放的內容。
char*str=(char*)malloc(sizeof(char)*13);
上面這條代碼,malloc()函數分配的地址一開始是void * 類型的,由於咱們用來存放char類型數據,因此強制轉換爲 char * 。