2012-09-30 69 views
7

當測試NULL時,我看到很多使用!var的代碼。是否有理由使用這種測試,而不是更明確的var == NULL。同樣,if (var)對於非空項目是一個正確的測試嗎?應該使用`!var`還是`var == NULL`?

+0

由於正式的原因,我更喜歡後者 - 它使意圖更清晰。但任一個都可以接受。 –

+0

發現一個非常類似的問題:http://stackoverflow.com/questions/459743/is-null-always-false [C/C++檢查NULL指針(的 – Matt

+0

可能重複http://stackoverflow.com/questions/ 3825668/cc-checking-for-null-pointer) –

回答

11

之間的差異:

!var

var == NULL

是在第二種情況下,編譯器必須發出診斷如果var是指針類型的不和NULL是用演員定義(如(void *) 0)。

此外(如評論中的@bitmask指出的)要使用NULL宏,您需要包含一個標準頭,該標頭定義了宏NULL。在C中,NULL宏定義在幾個頭文件中以方便使用(如stddef.h,stdio.h,stdlib.h,string.h等)。

否則這兩個表達式是等價的,它只是一個口味問題。使用你覺得更舒適的那個。

而對於第二個問題if (var)if (var != NULL)相同,但區別在於上述差異。

+2

請注意,您至少需要定義一個用於「NULL」的多個標頭。 – bitmask

+0

@bitmask好點,我把它添加到我的答案。 – ouah

+0

http://c-faq.com/null/ptrtest.html說'if(var)等價於if(var!= 0)'和更多關於空指針的東西。也不是已經問過這個問題嗎?請參閱http://stackoverflow.com/a/3825704/1273830它是不同的somehome? – Prasanth

2

ISO/IEC 9899標準指出:

  1. 作爲語言的:一個整數常量表達式與值0,或這樣的轉換爲類型void *一個表達式,被稱爲空指針常數。如果一個空指針常量被轉換爲一個指針類型,那麼稱爲空指針的結果指針將被保證與指向任何對象或函數的指針進行比較。

  2. 作爲庫:NULL是一個擴展到實現定義的空指針常量的宏。

這意味着您給出的表達式同樣是「正確的」。偏好一種形式而非另一種形式的原因很大程度上是品味的問題。

+0

也就是說,如果你有一個最小化的編譯器,沒有超出標準要求的警告。如果你有一個現代的,比如說一個在1991年後製作的,如果你試圖比較一個非指針變量和NULL,你會得到編譯器警告。 – Lundin

+0

這就是爲什麼我們有:'gcc -w' – geocar

2

從C標準:

運算類型和指針類型被統稱爲標量類型

一元+或 - 運算符的操作數應具有算術類型; 〜運算符, 整型;的!運算符,標量類型。

邏輯否定運算符的結果!如果其操作數的值與 不等於0,則其值爲0,如果其操作數的值等於0,則爲0。結果的類型爲int。表達式!E相當於(0 == E)。

所以,這應該回答你的問題。

+0

它不是真的,除非你知道如何定義NULL。 –

2

var == NULL版本有一個主要優勢:它使編譯器和靜態分析器可以找到一個特定的常見錯誤。

假設「VAR」是不是指針,但分配的變量。然後if(!var)會成爲未被發現的錯誤。

NULL常被聲明爲#define NULL ((void*)0)。該聲明不是該標準的強制性聲明,而是最常見的聲明之一。然後用半像樣的類型檢查的編譯器將能夠產生一個預警代碼:

int var = ...; 
if(var == NULL) // compiler warning, var is not a pointer 

除了上述優點外,還文體正確不使用!運營商,因爲它是一個邏輯運算符,意圖用於布爾變量,而不是指針。由於C沒有強大的打字功能,它就可以工作。

我建議在這個問題上遵循MISRA-C,這要求對NULL或零的檢查應該明確。 if(x != NULL)而不是if(x)。這些規則的基本原理是更易讀的代碼。無論如何,它可以轉換爲完全相同的機器代碼,因此在使代碼更易於閱讀方面沒有任何壞處。

相關問題