如果你有這樣的NSString * someString的對象,有什麼區別,如果有的話,! VS在Objective-C ==零
VS 感謝之間if (!someString)
if (someString == nil)
!
如果你有這樣的NSString * someString的對象,有什麼區別,如果有的話,! VS在Objective-C ==零
VS 感謝之間if (!someString)
if (someString == nil)
!
第一語法使用:
if (!someString)
利用一種的C「模糊」的事實,C的原標準缺乏適當的布爾類型派生的。因此,任何等於0的整數值被解釋爲「假」,並且不同於「0」的任何整數值被視爲「真」。因此,根據這個約定定義!
的含義,並且C標準的當前版本保持了兼容性的原始定義。
在特定情況下,someString
是一個指針,所以它首先被轉換爲一個整數,那麼! someString
被解釋爲的true
bool值時someString
點在位置0x000000
,否則evals爲「true」。
這是在大多數情況下(我總是說)的罰款,但在理論上,NULL/nil
could be different from 0x000000
在一定的編譯器,所以(在極理論),這將是更好地使用第二語法,這是比較明確的:
if (someString == nil)
它無論如何更具可讀性,因爲someString
不是一個整數(而是一個指針),海事組織,通常更好的做法。
編輯:關於NULL的定義...
無論是C標準定義NULL爲0對我來說是一個有趣的話題...
根據C99 standard,部分7.17, 「通用定義」:
NULL [其]擴展到一個實現定義空指針常數;
所以,NULL在STDDEF.H定義爲一個實現定義的空指針常量 ... 相同的文檔頁面上47個州:
一個整數常量表達式與值0,或者類型爲void *的表達式被稱爲空指針常量。如果空指針常量被轉換爲指針類型,那麼稱爲空指針的結果指針保證將不等於指針到任何對象或功能。
所以,空指針常數(其是(void*)0
)可以是轉換爲空指針,這是保證比較不等的指針的任何對象或功能。
所以,我覺得基本上這取決於是否執行決定一個空指針常量轉換爲空指針的結果產生一個指針,它轉換回整數給出0目前尚不清楚一個空指針解釋爲一個整數等於0.
我會說標準確實嘗試並強制空指針爲0,但將門打開爲systems where the null pointer was not 0。
在你的情況下,它意味着同樣的事情。任何不指向nil
的指針將返回YES
(true)。
正常情況下,感嘆號運算符會取消BOOL
的值。
對於大多數指針,它們是等價的,儘管我認識的大多數編程者更喜歡前者,因爲它更簡潔。
對於弱鏈接符號,前者解析該符號(並且如果缺失則會導致崩潰),而對nil
或NULL
的明確比較則不會。
!
是否定運算符。如果你的對象沒有被分配,你將會從一個真值表中獲得和== nil
操作一樣的結果。
但是!通常更多地用於布爾操作。
if(!isFalse) {
//if isFalse == NO, then this operation evaluates to YES (true)
[self doStuff];
}
當一個對象喜歡!something
它只是檢查是否指針指向nil
,如果它不使用!
,它返回true,if語句火災。
如果你的意思是測試條件「foo is nil」,你應該這樣說:foo == nil
。
如果你的意思是測試虛假的布爾值,!foo
沒問題,但是我個人認爲一個瘦小的感嘆號很容易錯過,所以我更喜歡foo == NO
。
編寫優秀的代碼是爲了清楚地將您的意圖傳達給編譯器,而不是傳給您的下一位程序員(可能是您的未來)。在這兩種情況下,你可以對你想要做的事情越明確,越好。
所有這一切,!
和==nil
在我能想到的所有情況下都具有相同的效果。
C語言中的砰砰聲,歎號,!
前綴運算符是邏輯上不是。至少,它的一個版本。如果你看着一個典型的邏輯不真值表,你會看到這樣的內容:
Input Result
1 0
0 1
但是在C中的邏輯沒有運營商做更多的東西是這樣的:
Input Result
non-zero 0
0 1
所以,當你考慮到這兩個Objective-C中的NULL和nil評估爲0,您知道應用於它們的邏輯非運算符將導致1。
現在,考慮等於==
算子。它比較兩個項目的值,如果相等則返回1,如果不相等則返回0。如果你把它的結果映射到一個真值表,那麼它看起來就像邏輯結果一樣。
在C和Objective-C程序中,條件性實際上是由int的,而不是真正的布爾值。這是因爲在C.所以寫的東西像這樣的布爾數據類型沒有這樣的事情的作品用C完美的罰款:
if(5) printf("hello\n"); // prints hello
,另外
if(2029) printf("hello\n"); // also prints hello
基本上,任何非零INT將評估爲「真」在C.你結合起來,與邏輯否定和平等的真值表和,你就會發現:
(! someString) and (someString == nil)
是所有意圖ID entical!
所以下一個合乎邏輯的問題是,爲什麼更喜歡一種形式而不是另一種?從純C視點這將是主要的風格的一個點,但大多數(好)的開發人員會選擇一些原因,等價測試:
「任何非零整數將在C中評估爲'真' 請您更具體地解釋邏輯表達式如何評估爲(int)0或(int)1?說,[如果(指針)...],指針首先轉換爲int [(int)指針],然後[如果((int)指針!= 0)]它計算爲(int)1。它可能是指針是64位,而int是32位,當它被轉換爲int時,高位字節被截斷(if(0xffffffff00000000)=> if((int)0x00000000))?我很高興看到我可能會錯的地方。 –
我給了+1,但C中沒有含糊的布爾值的概念 - 它根本不存在。 – Perception
NULL被C標準定義爲'0'或'(void *)0'。即使用於空指針值的底層位模式不同,它也不會改變C中空指針常量表示爲'0'或'(void *)0'的事實。 – dreamlax
@Perception:它在C99中。查看'_Bool'。 – JAB