天天看點

C語言中幾個數互不相等_再論c語言裡面的void類型本質和NULL

void類型本質 1 程式設計語言類型: (1) 程式設計語言分兩種:強類型語言和弱類型語言(比如PHP..n它就是弱類型語言);強類型語言中所有的變量都有自己固定的類型,這個類型有固定的記憶體占用,有固定的解析方法;而弱類型語言中沒有類型的概念,所有變量全都是一個類型(一般都是字元串的)程式在用的時候再根據需要來處理變量。 (2) c語言就是典型的強類型語言,c語言中所有的變量都有明确的類型;因為c語言中的一個變量都要對應記憶體中的一段記憶體,編譯器需要這個變量的類型來确定這個變量占用記憶體的位元組數和這一段記憶體的解析方法。 2 資料類型的本質含義: (1) 資料類型的本質就決定變量的記憶體占用數,和記憶體的解析方法。 (2) 是以得出結論:c語言中變量必須有确定的資料類型,如果一個變量沒有确定的類型(就是所謂的無類型)會導緻編譯器無法給這個變量配置設定記憶體,也無法解析這個變量對應的記憶體,是以得出結論不可能有沒有類型的變量。 (3) 但是c語言中可以有沒有類型的記憶體;在記憶體還沒有和具體的變量相綁定之前,記憶體就可以沒有類型。實際上純粹的記憶體就是沒有類型的,記憶體隻是因為和具體的變量相關聯後才有了确定的類型(其實記憶體自己本身是不知道的,但是我們編譯器知道,我們程式在使用這個記憶體時知道是以會按照類型的含義去進行記憶體的讀和寫)。 3 void類型的本質: (1)void類型的正确的含義是:不知道類型,不确定類型,還沒确定類型。 (2)比如說:void  a;它定義了一個void類型的變量,含義就是說a是一個變量,而且a肯定有确定的類型,隻是目前我還不知道a的類型,還不确定,是以标記為void。 4 為什麼需要void類型: (1) 什麼情況下需要void類型呢?其實就是在描述一段還沒有具體使用的記憶體時需要使用類型。 (2)  void的一個典型應用,想必大多數讀者都看到過,就是malloc的傳回值; 我們知道malloc向系統堆管理器申請一段記憶體給目前程式使用,malloc傳回的是一個指針,這個指針指向申請的那段記憶體。 malloc剛申請的這段記憶體尚未用來存儲資料,malloc函數也無法預知這段記憶體将來被存放什麼類型的資料,是以malloc無法傳回具體類型的指針,解決方法就是傳回一 個void *類型,告訴外部我傳回的是一段幹淨的記憶體空間,尚未确定類型。 是以我們在這個malloc函數之後可以給這段記憶體讀寫任意類型的資料。 下面是malloc函數的原型:

#include 
           

(3)  void *類型的指針指向的記憶體是尚未确定類型的,是以我們後續可以使用強制類型轉換強行将其轉換為各種類型; 這就是void類型的最終歸宿,就是被強制類型轉換成一個具體類型。 (4) void 類型使用時一般都是用void *,而不是僅僅使用void。 NULL 新媒體排版 1 NULL在C/C++中的标準定義: (1) NULL不是C語言關鍵字,本質上是一個宏定義。 (2) NULL的标準定義:

   #ifdef _cplusplus            // 條件編譯#define NULL 0#else#define NULL (void *)0        // 這裡對應C語言的情況#endif
           

解釋:C++的編譯環境中,編譯器預先定義了一個宏_cplusplus,程式中可以用條件編譯來判斷目前的編譯環境是C++的還是C的。NULL的本質解析:NULL的本質是0,但是這個0不是當一個數字解析,而是當一個記憶體位址來解析的,這個0其實是0x00000000,代表記憶體的0位址。(void *)0這個整體表達式表示一個指針,這個指針變量本身占4位元組,位址在哪裡取決于指針變量本身,但是這個指針變量的值是0,也就是說這個指針變量指向0位址(實際是0位址開始的一段記憶體)。

2 從指 針角度了解NULL的本質:

(1) int *p; p是一個函數内的局部變量,則p的值是随機的,也就是說p是一個野指針。

(2) int *p = NULL; p是一個局部變量,配置設定在棧上的位址是由編譯器決定的,我們不必關心,但是p的值是(void *)0,實際就是0,意思是指針p指向記憶體的0位址處。這時候p就不是野指針了。

(3) 為什麼要讓一個野指針指向記憶體位址0處?主要是因為在大部分的CPU中,記憶體的0位址處都不是可以随便通路的(一般都是作業系統嚴密管控區域,是以應用程式不能随便通路)。是以野指針指向了這個區域可以保證野指針不會造成誤傷。如果程式無意識的解引用指向0位址處的野指針則會觸發段錯誤。這樣就可以提示你幫助你找到程式中的錯誤。

3 為什麼需要NULL:

(1) 第一個作用就是讓野指針指向0位址處安全。

(2) 第二個作用就是一個特殊标記。按照标準的指針使用步驟是:

int *p = 
           

注意:一般比較一個指針和NULL是否相等不寫成if (p == NULL),而寫成if (NULL == p)。原因是第一種寫法中如果不小心把==寫成了=,則編譯器不會報錯,但是程式的意思完全不一樣了;而第二種寫法如果不小心把==寫成了=則編譯器會發現并報錯。

4 注意不要混用NULL與'\0':

(1) '\0' 和 '0' 和 0  和 NULL幾個區分開。

(2) '\0'是一個轉義字元,他對應的ASCII編碼值是0,本質就是0。

(3) '0'是一個字元,他對應的ASCII編碼值是48,本質是48。

(4) 0是一個數字,他就是0,本質就是0。

(5) NULL是一個表達式,是強制類型轉換為void *類型的0,本質是0.

總結:'\0'用法是C語言字元串的結尾标志,一般用來比較字元串中的字元以判斷字元串有沒有到頭;'0'是字元0,對應0這個字元的ASCII編碼,一般用來擷取0的ASCII碼值;0是數字,一般用來比較一個int類型的數字是否等于0;NULL是一個表達式,一般用來比較指針是否是一個野指針。

C語言中幾個數互不相等_再論c語言裡面的void類型本質和NULL

關注公衆号,每周分享至少3篇開源技術幹貨,文章中如有沒看懂的地方可以私聊我,我看到了會立馬回複你,個人微信号:a18879499804,在看的話,幫忙點個贊,非常感謝!

C語言中幾個數互不相等_再論c語言裡面的void類型本質和NULL
C語言中幾個數互不相等_再論c語言裡面的void類型本質和NULL

文章後記

C語言中幾個數互不相等_再論c語言裡面的void類型本質和NULL

    這裡是公衆号:“最後一個bug”,感謝各位的關注,這裡将是幫你找到最後一個bug的技術研究基地。下期精彩見!

推薦好文   點選藍色字型即可跳轉

☞【硬殼】C程式裡面嵌點"機器碼"玩一玩"(小知識揭露大道理)

C語言中幾個數互不相等_再論c語言裡面的void類型本質和NULL

☞頓悟,神秘的register關鍵字(C語言篇) 

C語言中幾個數互不相等_再論c語言裡面的void類型本質和NULL

☞【典藏】深度剖析單片機程式的運作(C程式版) 

C語言中幾個數互不相等_再論c語言裡面的void類型本質和NULL

☞【連載】通過"庫檔案"學單片機驅動程式設計(5)-完結篇

C語言中幾個數互不相等_再論c語言裡面的void類型本質和NULL

☞C語言為什麼一般不在.h中定義函數或者變量?(精華)

C語言中幾個數互不相等_再論c語言裡面的void類型本質和NULL

☞手把手教你寫Modbus-RTU協定(理論篇)

C語言中幾個數互不相等_再論c語言裡面的void類型本質和NULL

☞單片機開發之節省記憶體大法(C語言版本)

C語言中幾個數互不相等_再論c語言裡面的void類型本質和NULL

☞嵌入式程式設計之動态接口技術(經驗幹貨)

C語言中幾個數互不相等_再論c語言裡面的void類型本質和NULL

☞【典藏】自制小型GUI界面架構(設計思想篇)

C語言中幾個數互不相等_再論c語言裡面的void類型本質和NULL

繼續閱讀