簡體   English   中英

#define TRUE !FALSE vs #define TRUE 1

[英]#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

要了解原因,請記住數組索引是可交換的(請參閱此問題我的回答,並且索引運算符[]綁定比!更緊密。

這里的教訓是:

  1. 對於任何打算用作表達式的宏,整個宏定義都應該括在括號中——即使您想不出有什么重要的情況。

  2. 把事情簡單化。 在 C 中, 0是唯一的假值, 1是規范的真值。 (任何非零值都是“真”,但內置的“布爾”運算符總是產生01 。)使用! 運算符將TRUE定義為FALSE (反之亦然)只是一種不必要的復雜化。

如果可以,請使用<stdbool.h> 如果你不能(因為你堅持使用 C99 之前的編譯器),我建議這樣做:

typedef enum { false, true } bool;

它與 C99 的_Bool / bool不太一樣(轉換到這種bool類型沒有標准化為01 ),但它幾乎可以滿足所有用途。

差別不大。

#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。沒問題。

他們只是一樣。

  • !01所以!FALSE1

#define TRUE !FALSE根本沒有技術優勢,盡管它存在很長時間並且出現在很多地方。

#define TRUE !FALSE可能會被誤解,人們可能認為TRUE代表每個不是0值。

  • 只有1等於TRUE ,其他值如23255 ...(其中!=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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM