C語言知識彙總| 56-C語言NULL空指標以及void指標 - IT人

文章推薦指數: 80 %
投票人數:10人

NULL 是“零值、等於零”的意思,在C語言中表示空指標。

從表面上理解,空指標是不指向任何資料的指標,是無效指標,程式使用它不會產生效果。

Togglenavigation IT人 IT人 C語言知識彙總|56-C語言NULL空指標以及void指標 Neutionwei發表於 2020-10-01 一、NULL空指標 一個指標變數可以指向計算機中的任何一塊記憶體,不管該記憶體有沒有被分配,也不管該記憶體有沒有使用許可權,只要把地址給它,它就可以指向,C語言沒有一種機制來保證指向的記憶體的正確性,程式設計師必須自己提高警惕。

很多初學者會在無意間對沒有初始化的指標進行操作,這是非常危險的,請看下面的例子: #include intmain() { char*str; gets(str); printf("%s\n",str); return0; } 這段程式沒有語法錯誤,能夠通過編譯和連結,但當使用者輸入完字串並按下Enter鍵時就會發生錯誤,在Linux下表現為段錯誤(SegmentFault),在Windows下程式直接崩潰。

如果你足夠幸運,或者輸入的字串少,也可能不報錯,這都是未知的。

未初始化的區域性變數的值是不確定的,C語言並沒有對此作出規定,不同的編譯器有不同的實現,因此不要直接使用未初始化的區域性變數。

上面的程式碼中,str就是一個未初始化的區域性變數,它的值是不確定的,究竟指向哪塊記憶體也是未知的,大多數情況下這塊記憶體沒有被分配或者沒有讀寫許可權,使用gets()函式向它裡面寫入資料顯然是錯誤的。

建議對沒有初始化的指標賦值為NULL,例如: char*str=NULL; NULL是“零值、等於零”的意思,在C語言中表示空指標。

從表面上理解,空指標是不指向任何資料的指標,是無效指標,程式使用它不會產生效果。

注意區分大小寫,null沒有任何特殊含義,只是一個普通的識別符號。

很多庫函式都對傳入的指標做了判斷,如果是空指標就不做任何操作,或者給出提示資訊。

更改上面的程式碼,給str賦值NULL,看看會有什麼效果: #include intmain() { char*str=NULL; gets(str); printf("%s\n",str); return0; } 執行程式後發現,還未等使用者輸入任何字元,printf()就直接輸出了(null)。

我們有理由據此推斷,gets()和printf()都對空指標做了特殊處理: gets()不會讓使用者輸入字串,也不會向指標指向的記憶體中寫入資料;printf()不會讀取指標指向的內容,只是簡單地給出提示,讓程式設計師意識到使用了一個空指標。

我們在自己定義的函式中也可以進行類似的判斷,例如: voidfunc(char*p) { if(p==NULL){ printf("(null)\n"); }else{ printf("%s\n",p); } } 這樣能夠從很大程度上增加程式的健壯性,防止對空指標進行無意義的操作。

其實,NULL是在stdio.h中定義的一個巨集,它的具體內容為: #defineNULL((void*)0) (void*)0表示把數值0強制轉換為void*型別,最外層的()把巨集定義的內容括起來,防止發生歧義。

從整體上來看,NULL指向了地址為0的記憶體,而不是前面說的不指向任何資料。

在程式的虛擬地址空間中,最低地址處有一段記憶體區域被稱為保留區,這個區域不儲存有效資料,也不能被使用者程式訪問,將NULL指向這塊區域很容易檢測到違規指標。

在大多數作業系統中,極小的地址通常不儲存資料,也不允許程式訪問,NULL可以指向這段地址區間中的任何一個地址。

注意,C語言沒有規定NULL的指向,只是大部分標準庫約定成俗地將NULL指向0,所以不要將NULL和0等同起來,例如下面的寫法是不專業的: int*p=0; 而應該堅持寫為: int*p=NULL; 注意NULL和NUL的區別:NULL表示空指標,是一個巨集定義,可以在程式碼中直接使用。

而NUL表示字串的結束標誌'\0',它是ASCII碼錶中的第0個字元。

NUL沒有在C語言中定義,僅僅是對'\0'的稱呼,不能在程式碼中直接使用。

二、void*指標 對於空指標NULL的巨集定義內容,上面只是對((void*)0)作了粗略的介紹,這裡重點說一下void*的含義。

void用在函式定義中可以表示函式沒有返回值或者沒有形式引數,用在這裡表示指標指向的資料的型別是未知的。

也就是說,void*表示一個有效指標,它確實指向實實在在的資料,只是資料的型別尚未確定,在後續使用過程中一般要進行強制型別轉換。

C語言動態記憶體分配函式malloc()的返回值就是void*型別,在使用時要進行強制型別轉換,請看下面的例子: #include intmain() { //分配可以儲存30個字元的記憶體,並把返回的指標轉換為char* char*str=(char*)malloc(sizeof(char)*30); gets(str); printf("%s\n",str); return0; } 執行結果: https://blog.csdn.net↙ https://blog.csdn.net   相關文章 R語言處理.nc檔案(landcover)繪製土地覆蓋變化趨勢圖 2020-11-20 LeetCode-844.比較含退格的字串(棧、雙指標) 2020-11-20 LeetCode C語言解讀assert函式 2020-11-20 初學計算機語言者(C語言,C++,java,pytion,C#) 2020-11-21 JavaC++C# C語言列舉資料型別 2020-11-21 C語言I部落格作業05 2020-11-21 填充每個節點的下一個右側節點指標 2020-11-21 PID演算法的C語言實現 2020-11-21 演算法 C語言瑣碎知識 2020-11-21 Avoidedredundantnavigationtocurrentlocation:"/users" 2020-11-21 Java設計模式-17、直譯器模式-自定義語言的實現 2020-11-22 Java設計模式 作業系統實驗:銀行家演算法(C語言) 2020-11-22 演算法 形式語言與自動機:實驗二——DFA識別句子 2020-11-22 Java語言搭建介面自動化框架學習一(單介面請求和響應) 2020-11-22 Java框架 C語言小白走過的彎路 2020-11-22 組合語言-學習記錄(二) 2020-11-22 (2)verilog與Systemverilog兩種語言編寫打兩拍 2020-11-22 SQL語句中聚合函式忽略NULL值的總結 2020-11-22 SQL C語言練習——資料加密 2020-11-22 加密 C語言入門基礎 2020-11-22 最新文章 StrategyAnalytics:2022年Q1全球智慧音響出貨量下降5% Canalys:2022年Q1中國雲基礎設施服務支出同比增長21% SOLIDWORKS2022教育版的優勢有哪些 攝取轉碼的媒體應用MediaEncoder2022 一套MVC5+EasyUI企業快速開發框架原始碼BS開發框架原始碼 沙盒冒險遊戲:泰拉科技TerraTechMac中文版 Ai實現FPS遊戲自動瞄準yolov5fps自瞄 TopazDeNoiseAIformac(AI影像降噪軟體)支援m1 誰有OracleSupportIdentifier帳號,幫我下載一個漏洞補丁,萬分感謝。



膜拜。



MovaviPicverseforMac(專業照片編輯軟體) Mac電影特效合成軟體:NUKE13 物聯網開源開發平臺Shifu開放內測!第一版技術文件釋出



請為這篇文章評分?