1. 程式人生 > >c和c++中NULL和0的區別?!

c和c++中NULL和0的區別?!

4,空指標(null pointer)指向了記憶體的什麼地方(空指標的內部實現)?

標準並沒有對空指標指向記憶體中的什麼地方這一個問題作出規定,也就是說用哪個具體的地址值(0x0 地址還是某一特定地址)表示空指標取決於系統的實現。我們常見的空指標一般指向 0 地址,即空指標的內部用全 0 來表示(zero null pointer,零空指標);也有一些系統用一些特殊的地址值或者特殊的方式表示空指標(nonzero null pointer,非零空指標),具體請參見C FAQ。

幸運的是,在實際程式設計中不需要了解在我們的系統上空指標到底是一個 zero null pointer 還是 nonzero null pointer,我們只需要瞭解一個指標是否是空指標就可以了——編譯器會自動實現其中的轉換,為我們遮蔽其中的實現細節。注意:不要把空指標的內部表示等同於整數 0 的物件表示——如上所述,有時它們是不同的。

5,如何判斷一個指標是否是一個空指標?

這可以通過與空指標常量或者其它的空指標的比較來實現(注意與空指標的內部表示無關)。例如,假設 p 是一個指標變數,q 是一個同類型的空指標,要檢查 p 是否是一個空指標,可以採用下列任意形式之一——它們在實現的功能上都是等價的,所不同的只是風格的差別。

指標變數 p 是空指標的判斷:

if ( p == 0 )

if ( p == '\0' )

if ( p == 3 - 3 )

if ( p == NULL )  /* 使用 NULL 必須包含相應的標準庫的標頭檔案 */

if ( NULL == p )

if ( !p )

if ( p == q )

...

指標變數 p 不是空指標的判斷:

if ( p != 0 )

if ( p != '\0' )

if ( p != 3 - 3 )

if ( p != NULL )  /* 使用 NULL 必須包含相應的標準庫的標頭檔案 */

if ( NULL != p )

if ( p )

if ( p != q )

...

6,可以用 memset 函式來得到一個空指標嗎?

這個問題等同於:如果 p 是一個指標變數,那麼

memset( &p, 0, sizeof(p) ); 和 p = 0;

是等價的嗎?

答案是否定的,雖然在大多數系統上是等價的,但是因為有的系統存在著“非零空指標” (nonzero null pointer),所以這時兩者不等價。由於這個原因,要注意當想將指標設定為空指標的時候不應該使用 memset,而應該用空指標常量或空指標對指標變數賦值或者初始化的方法。

7,可以定義自己的 NULL 的實現嗎?兼答"NULL 的值可以是 1、2、3 等值嗎?"類似問題

[7.1.3-2] If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), or defines a reserved identifier as a macro name, the behavior is undefined.

NULL 是標準庫中的一個符合上述條件的 reserved identifier (保留識別符號)。所以,如果包含了相應的標準標頭檔案而引入了 NULL 的話,則再在程式中重新定義 NULL 為不同的內容是非法的,其行為是未定義的。也就是說,如果是符合標準的程式,其 NULL 的值只能是 0,不可能是除 0 之外的其它值,比如 1、2、3 等。

8,malloc 函式在分配記憶體失敗時返回 0 還是 NULL?

malloc 函式是標準 C 規定的庫函式。在標準中明確規定了在其記憶體分配失敗時返回的是一個 “null pointer”(空指標):

[7.20.3-1] If the space cannot be allocated, a null pointer is returned.

對於空指標值,一般的文件(比如 man)中傾向於用 NULL 表示,而沒有直接說成 0。但是我們應該清楚:對於指標型別來說,返回 NULL 和 返回 0 是完全等價的,因為 NULL 和 0 都表示 “null pointer”(空指標)。(tyc:一般系統中手冊中都返回NULL,那我們就用NULL吧)

另外,附C FAQ上關於null pointer的解釋:C FAQ:null pointer

參考: