這兩天一直迷惑一個問題,就是如何判斷指針是否為空,通常有如下兩種方式(假設p為指針):
if (NULL == p) {
// ...
}
if (!p) {
}
到底哪種方式好呢?這個問題應該從兩個方面去考慮,本文就是圍繞這兩個問題展開的,僅限於C語言。
它們在語義、編譯等環節上是否等價?
它們在可讀性、可維護性等上面是否等價?
一、是否存在隱式類型轉換?
《C 程序設計語言中》規定(中文第二版177頁),對於運算符==和!=,可以作如下比較:指針可以和值為0的常量表達式或指向void的指針進行比較。而NULL在C中被定義為((void*)0),故NULL == p可以直接進行。
而175頁也同時規定,運算符!的運算分量必須是一個算術類型或指針。如果運算分量等於0,那么結果為1,否則結果為0。結果類型為int。
由上面的分析可以看出,上述兩個條件判斷都不需要進行隱式類型轉換。同時,我也在VC2008下面測試了一下,這兩種情況下的匯編都為如下形式:
1: 00971578 cmp dword ptr [p],0
2: 0097157C jne test1+0A3h (971583h)
更深一步的講,C99規范對運算符==和!也是有規定的,和《C 程序設計語言中》描述一致。第6.3.5節,第5點明確表示!E和0==E等價。參見下面的具體描述:
5 The result of the logical negation operator ! is 0 if the value of its operand compares
unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int.
The expression !E is equivalent to (0==E).
第6.5.9節中規定==兩邊的操作數,可以一邊是指針,一邊是指向void類型的指針;或者,一邊是指針一邊是空指針常量。參見下面的具體描述:
— one operand is a pointer to an object or incomplete type and the other is a pointer to a
qualified or unqualified version of void; or
— one operand is a pointer and the other is a null pointer constant.
二、可讀性
《C 程序設計語言中》中文第二版32-33頁講到運算符!時,建議使用!p而不要使用p == 0。但同時又提到在復雜的情況下可能難於理解。個人認為,!p的方式可以使代碼更短,看起來簡潔,NULL == p總覺得怪怪的。
三、結論
通過上面的分析,可以看到,這兩種方式沒有本質的區別。具體選哪種方式,一要看具體的邏輯表達式,而是要看代碼可讀性如何。