99热99这里只有精品6国产,亚洲中文字幕在线天天更新,在线观看亚洲精品国产福利片 ,久久久久综合网

歡迎加入QQ討論群258996829
麥子學院 頭像
蘋果6袋
6
麥子學院

C語言學習之空指針NULL以及void指針詳解

發(fā)布時間:2017-06-25 15:38  回復:0  查看:3450   最后回復:2017-06-25 15:38  
本文和大家分享的主要是c 語言 空指針NULL 以及 void 指針相關(guān)內(nèi)容,一起來看看吧,希望對大家 學習c語言有所幫助。
   空指針 NULL
  一個指針變量可以指向計算機中的任何一塊內(nèi)存,不管該內(nèi)存有沒有被分配,也不管該內(nèi)存有沒有使用權(quán)限,只要把地址給它,它就可以指向,C 語言沒有一種機制來保證指向的內(nèi)存的正確性,程序員必須自己提高警惕。
  很多初學者會在無意間對沒有初始化的指針進行操作,這是非常危險的,請看下面的例子:
  1. #include
  2. int main () {
  3. char * str ;
  4. gets ( str );
  5. printf ( "%s \n " , str );
  6. return 0 ;
  7. }
  這段程序沒有語法錯誤,能夠通過編譯和鏈接,但當用戶輸入完字符串并按下回車鍵時就會發(fā)生錯誤,在 Linux  下表現(xiàn)為段錯誤( Segment Fault ),在  Windows  下程序直接崩潰。如果你足夠幸運,或者輸入的字符串少,也可能不報錯,這都是未知的。
  前面我們講過,未初始化的局部變量的值是不確定的,C 語言并沒有對此作出規(guī)定,不同的編譯器有不同的實現(xiàn),我曾警告大家不要直接使用未初始化的局部變量。上面的代碼中, str  就是一個未初始化的局部變量,它的值是不確定的,究竟指向哪塊內(nèi)存也是未知的,大多數(shù)情況下這塊內(nèi)存沒有被分配或者沒有讀寫權(quán)限,使用  gets()  函數(shù)向它里面寫入數(shù)據(jù)顯然是錯誤的。
  我強烈建議對沒有初始化的指針賦值為 NULL ,例如:
  char *str = NULL;
  NULL  零值、等于零 的意思,在 C 語言中表示空指針。從表面上理解,空指針是不指向任何數(shù)據(jù)的指針,是無效指針,程序使用它不會產(chǎn)生效果。
  注意區(qū)分大小寫,null  沒有任何特殊含義,只是一個普通的標識符。
  很多庫函數(shù)都對傳入的指針做了判斷,如果是空指針就不做任何操作,或者給出提示信息。更改上面的代碼,給 str  賦值  NULL ,看看會有什么效果:
  1. #include
  2. int main () {
  3. char * str = NULL ;
  4. gets ( str );
  5. printf ( "%s \n " , str );
  6. return 0 ;
  7. }
  運行程序后發(fā)現(xiàn),還未等用戶輸入任何字符,printf()  就直接輸出了  (null)  。我們有理由據(jù)此推斷,gets()  和  printf()  都對空指針做了特殊處理:
  · gets()  不會讓用戶輸入字符串,也不會向指針指向的內(nèi)存中寫入數(shù)據(jù);
  · printf()  不會讀取指針指向的內(nèi)容,只是簡單地給出提示,讓程序員意識到使用了一個空指針。
  我們在自己定義的函數(shù)中也可以進行類似的判斷,例如:
  1. void func ( char * p ) {
  2. if ( p == NULL ) {
  3. printf ( "(null) \n " );
  4. } else {
  5. printf ( "%s \n " , p );
  6. }
  7. }
  這樣能夠從很大程度上增加程序的健壯性,防止對空指針進行無意義的操作。
  其實,NULL  是在  stdio.h
  中定義的一個宏,它的具體內(nèi)容為:
  #define NULL ((void *)0)
   (void *)0  表示把數(shù)值 0  強制轉(zhuǎn)換為  void *  類型,最外層的  ( )  把宏定義的內(nèi)容括起來,防止發(fā)生歧義。從整體上來看,NULL 指向了地址為  的內(nèi)存,而不是前面說的不指向任何數(shù)據(jù)。
  在進程的虛擬地址空間中,最低地址處有一段內(nèi)存區(qū)域被稱為保留區(qū),這個區(qū)域不存儲有效數(shù)據(jù),也不能被用戶程序訪問,將NULL  指向這塊區(qū)域很容易檢測到違規(guī)指針。
  關(guān)于虛擬地址空間的概念以及程序的內(nèi)存分布,我們將在《  C語言和內(nèi)存  》專題中深入講解,現(xiàn)在讀者只需要記住,在大多數(shù)操作系統(tǒng)中,極小的地址通常不保存數(shù)據(jù),也不允許程序訪問,NULL  可以指向這段地址區(qū)間中的任何一個地址。
  注意,C 語言沒有規(guī)定  NULL  的指向,只是大部分標準庫約定成俗地將  NULL  指向  0 ,所以不要將  NULL  和  等同起來,例如下面的寫法是不專業(yè)的:
  int *p = 0;
  而應該堅持寫為:
  int *p = NULL;
  注意 NULL  和  NUL  的區(qū)別: NULL  表示空指針,是一個宏定義,可以在代碼中直接使用。而  NUL  表示字符串的結(jié)束標志  '\0' ,它是 ASCII 碼表中的第  個字符。 NUL  沒有在 C 語言中定義,僅僅是對  '\0'  的稱呼,不能在代碼中直接使用。
   void 指針
  對于空指針 NULL  的宏定義內(nèi)容,上面只是對  ((void *)0)  作了粗略的介紹,這里重點說一下 void *  的含義。void  用在函數(shù)定義中可以表示函數(shù)沒有返回值或者沒有形式參數(shù),用在這里表示指針指向的數(shù)據(jù)的類型是未知的。
  也就是說,  void *  表示一個有效指針,它確實指向?qū)崒嵲谠诘臄?shù)據(jù),只是數(shù)據(jù)的類型尚未確定,在后續(xù)使用過程中一般要進行強制類型轉(zhuǎn)換。
  C 語言動態(tài)內(nèi)存分配函數(shù)  malloc()  的返回值就是  void *
  類型,在使用時要進行強制類型轉(zhuǎn)換,請看下面的例子:
   純文本復制
  1. #include
  2. int main () {
  3. // 分配可以保存 30 個字符的內(nèi)存,并把返回的指針轉(zhuǎn)換為  char *
  4. char * str = ( char *) malloc ( sizeof ( char ) * 30 );
  5. gets ( str );
  6. printf ( "%s \n " , str );
  7. return 0 ;
  8. }
  運行結(jié)果:
  c.biancheng.net↙
  c.biancheng.net
  這里重點是讓大家理解  void * ,它不是空指針的意思,而是實實在在的指針,只是指針指向的內(nèi)存中不知道保存的是什么類型的數(shù)據(jù)。
來源:csdn
您還未登錄,請先登錄

熱門帖子

最新帖子

?