C語言學習之null 指標NULL以及void指標詳解

來源:互聯網
上載者:User

標籤:

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

C語言學習之null 指標NULL以及void指標詳解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.