[英]#define TRUE !FALSE vs #define TRUE 1
撇開自 c99 以來stdbool.h
已經存在的事實,在C
定義宏來處理布爾類型時,以下內容有什么區別嗎?
#define FALSE 0
#define TRUE 1 // Option 1
#define TRUE !FALSE // Option 2
從這里的現場示例來看,它似乎沒有什么區別。 這兩種選擇都有技術優勢嗎? (不包括第二個示例在使用 c++ bool
對象時效果更好的事實。)
ISO C 和 C99 都定義了!
像這樣。
邏輯否定運算符的結果! 如果其操作數的值比較不等於 0,則為 0,如果其操作數的值比較等於 0,則為 1。結果的類型為 int 。 表達式 !E 等價於 (0==E)。
所以!0
評估為1
。 給定符合標准的 C 編譯器,您的選項將具有相同的結果。 此外,沒有運行時懲罰,編譯器會在編譯時不斷地將!0
折疊為1
。
如果你想把這帶到邏輯上的極端並且不對真假做出假設......
#define TRUE (1==1)
#define FALSE (!TRUE)
無論使用哪種語言,這都具有始終正確的優點。 例如,在 shell 0 中通常被認為是“true”或“not an error”。
在 C 沒有達成一致的標准的時候,這種事情是不合時宜的。 例如, Code Complete 的第一版在第 369 頁提倡這一點。當它於 1993 年發布時,您的 C 編譯器很可能不符合 ISO 標准並且 stdbool.h 不存在。 “代碼完成”也適用於使用多種不同語言的多語言程序員。 有些,比如 shell 和 Lisp,對真理的定義不同。
選項 2 沒有任何好處,因為! 0
C 標准保證! 0
計算結果為 1。
以這種方式定義TRUE
是舊資料的主要內容,大概是為了遵循風格指南,該指南要求盡可能避免“魔法常數”。
#define FALSE 0
#define TRUE 1 // Option 1
#define TRUE !FALSE // Option 2
值沒有區別。 1
和!0
都是具有相同值1
int
類型的常量表達式(根據標准對!
運算符語義的定義)。
可能的區別在於第二個定義沒有正確加上括號。 請記住,宏擴展是以文本方式執行的。 在表達式中間擴展一個沒有括號的宏會導致運算符優先級問題。 我在這里寫了一個人為的例子。
自從一元!
運算符具有非常高的優先級,您不太可能遇到問題。 我能想到的唯一情況是,如果您將它用作索引運算符的前綴。 例如,給定:
int arr[] = { 10, 20 };
選項 1 給出:
TRUE[arr] == 20
而選項 2 給出:
TRUE[arr] == 0
要了解原因,請記住數組索引是可交換的(請參閱此問題和我的回答,並且索引運算符[]
綁定比!
更緊密。
這里的教訓是:
對於任何打算用作表達式的宏,整個宏定義都應該括在括號中——即使您想不出有什么重要的情況。
把事情簡單化。 在 C 中, 0
是唯一的假值, 1
是規范的真值。 (任何非零值都是“真”,但內置的“布爾”運算符總是產生0
或1
。)使用!
運算符將TRUE
定義為FALSE
(反之亦然)只是一種不必要的復雜化。
如果可以,請使用<stdbool.h>
。 如果你不能(因為你堅持使用 C99 之前的編譯器),我建議這樣做:
typedef enum { false, true } bool;
它與 C99 的_Bool
/ bool
不太一樣(轉換到這種bool
類型沒有標准化為0
或1
),但它幾乎可以滿足所有用途。
差別不大。
#define TRUE 1
比#define TRUE !FALSE
略有優勢,因為1
是不受運算符優先級影響的單個項目。
!FALSE
可以是(!FALSE)
來處理試圖使用++ -- [] . ->
神秘代碼++ -- [] . ->
++ -- [] . ->
,在FALSE
旁邊有更高的優先級。
在 C 語言中,TRUE 被正確定義為 (!FALSE),因為零 (0) 是 FALSE,FALSE 是零 (0),任何其他值都是 TRUE。 您幾乎可以將任何變量用作布爾表達式,如果它不為零,則表達式的值為 TRUE。 正是因為這個原因,NULL 指針為零。 字符串結尾字符 ('\\0') 也是如此。 已經編寫了大量代碼來利用這一事實。 考慮:
while ( *d++ = *s++ );
當字符串結束字符被復制時,復制將結束。 這個成語很常見。 別介意緩沖區大小問題。
這就是為什么如果您沒有現代專用布爾類型(其中唯一可能的值是 TRUE 和 FALSE),則測試是否等於 TRUE 是一個壞主意的原因之一。 無論如何,為了安全起見,我建議你養成測試不等式為 FALSE 的習慣。 您可能並不總是能夠使用新的和閃亮的。
沒有太大區別。 但我認為#define TRUE 1
更好。
如果您使用#define TRUE !FALSE
:
FALSE
是 0, TRUE
是所有數字都期望為 0。
如果您使用#define TRUE 1
:
FALSE
為 0, TRUE
為 1。沒問題。
他們只是一樣。
!0
是1
所以!FALSE
是1
#define TRUE !FALSE
根本沒有技術優勢,盡管它存在很長時間並且出現在很多地方。
#define TRUE !FALSE
可能會被誤解,人們可能認為TRUE
代表每個不是0
值。
1
等於TRUE
,其他值如2
、 3
、 255
...(其中!=0
)不等於TRUE
為了防止這種誤解,許多組織要求不再使用#define TRUE !FALSE
或與TRUE
比較應更改為!FALSE
:
// Should not
if (var_bool == TRUE) {
...
}
//Should
if (var_bool != FALSE) {
...
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.