2012-08-14 43 views
15

在C++或從C99,如何爲布爾值定義小於運算符<排序的布爾值

或者,解釋這種代碼的行爲:

#ifndef __cplusplus 
#include <stdbool.h> 
#endif 
#include <stdio.h> 

int main() { 
    bool b = -1; 
    if(b < true) { 
     printf("b < true\n"); 
    } 
    if(b < false) { 
     printf("b < false\n"); 
    } 
    if(true < false) { 
     printf("true < false\n"); 
    } 
    if(false < true) { 
     printf("false < true\n"); 
    } 
} 

在MSVC版本10,編譯爲C++代碼,GCC 4.6.3-ubuntu5編譯爲C代碼和G ++ 4.6.3-1ubuntu5編譯爲C++代碼中,你得到的是

false < true 

也就是說,下面的不等式都是false

(bool)-1 < true 
(bool)-1 < false 
true < false 

而下面是true

false < true 

回答

13

在C++(我用C懷疑爲好),bool我們比較彷彿正是 false0true1。並且如果類型是bool,則不可以使用除truefalse以外的其他 值。

當比較bool到其它數值類型,它會轉換爲int, 再次false轉換爲0true轉換爲1

編輯: C++和stdbool.h在C99也迫使布爾值是0(假)或1(真) - bool b = -1;設置的b至1的值。由於1 < 11 < 0均爲假,則不等式在問題中是正確的。

編輯:(by James)除了上面的編輯不是真正正確的,至少在C++中爲 。 A bool的值不是0或1,它的值爲 的值爲falsetrue。只有當它被升級到int時, 轉換纔會創建01的值。

而且Konrad指出,沒有比較bool值。 的「通常的算術轉換」爲發生的比較運算符, 這意味着在兩個操作數,這意味着 bool轉換爲int(一樣charshort ...或枚舉)的積分的推廣。

所有這些都是相當技術性的。在實踐中,您可以記住 false < true,或者您可以考慮false爲0,並且true爲1, ,以最適合您的爲準。唯一要記住的重要的事情是 ,即一個bool可以有其他值。

(有趣的是,我不認爲一個bool的位模式是由標準強加 。實現可能使用的位模式 0x550xAA,例如,只要所有轉換的 積分型,得到0和1,轉換到bool總是給出 適當的值等。其中零初始化靜態 變量)

以及一個最終注:bool b = -1;b套到-1 != 0(這是 true,而不是1,但當然,true將在任何 數字上下文中轉換爲1

+0

你能找到標準中定義的位置嗎?我只是看着,無法找到它(我甚至不知道要搜索什麼)。 – 2012-08-14 12:07:04

+0

@Mansuro Irrelevant,James和我在談論C++。但即使對於C,本文檔中也沒有說明如何處理轉換'(bool)-1'。 – 2012-08-14 12:10:02

+0

§4.5積分促銷。 「類型'bool'的右值可以轉換爲 類型爲'int'的右值,其中'false'變成零,'true'變成 之一。 (請注意,'bool'從來沒有'0'或'1'值;只有'false'和'true',這就是爲什麼我說「確切地說_as if_」)和§4.12爲 轉換爲' bool'。 – 2012-08-14 12:13:13

1

操作>並在此基礎<:

true == (1) 
false == (0) 

此假: (布爾)-1 <真 (布爾)-1 <假 由於bool b = -1中的滾動運算;

1

bool似乎被定義爲(有符號)整數類型,false爲0,零爲1.這解釋了爲什麼true> false(1> 0)爲真。

此外,將-1與無符號數進行比較會導致-1被轉換爲無符號數,並且在您的平臺上,這會導致整數溢出,從而導致UINT_MAX(或任何類型的bool已被typedeffed)。這現在解釋了爲什麼下面的表達式是錯誤的:

((bool)-1) < true i. e. UINT_MAX < 1 
((bool)-1) < false i. e. UINT_MAX < 0 
true < false i. e. 1 < 0 
+1

形式上,'bool'被定義爲一個有符號(不是無符號)整數類型,儘管它唯一可以使用的值('true'和'false')都具有非負值。並且'((bool)-1)'不是'UINT_MAX',當被認爲是'int'時它是'1'。 – 2012-08-14 12:05:40

+0

bool不是unsigned int,它被定義爲int http://gel.sourceforge.net/examples/stdbool_8h-source.php – Mansuro 2012-08-14 12:08:19

+0

在C'_Bool'(作爲'bool'背後的基礎類型)被定義爲一個無符號整數類型。與'0'不同的所有值被轉換爲'bool',結果爲值'1'。所以'(bool)-1'總是'1',因此' 2012-08-14 12:13:45

4

這非常合理。整數類型=> bool轉換實際上是b = i != 0。爲了做<比較,它通過規則false => 0和true => 1將bool提升爲int。在你的第一種情況下,-1將等同於真,並且兩者都會升至1,因此這是錯誤的。顯然,對於第二和第三種情況,1不會小於0,而在最後一種情況下爲0 < 1

1

對於C++只是false < true

對於C是比較難回答。我看到

typedef char _Bool; /* For C compilers without _Bool */我stdbool.h

看來,如果編譯器支持_Bool,它的工作原理是在C++中,並自動轉換爲0/1,但如果沒有它應該工作爲char,這將是​​,b < false如果炭簽署

對於我(INT)(布爾)-1是即使在C 1,所以bool被定義爲不燒焦

+0

你的編譯器似乎不符合C99或C11,如果它真的這樣做'typedef'。 '_Bool'是一個無符號整數類型,它可以保存值'0'和'1',並且所有不同於'0'的值都被轉換爲'1',例如在'(bool)-1'中。 (後者將無法正確使用'char'作爲替代品。)由於這是一個整數類型,所以可能值的排序與所有整數類型相同,「0」小於「1」。 – 2012-08-14 12:18:03

2

布爾值排序,使得false小於true。根據標準,bool只能保存兩個值:truefalse,因此(bool)-1中的轉換應產生true(因爲轉換爲bool時所有非0值都是true)。這是clang和g ++中的行爲 - 4.7。

實際的比較(我認爲)是bool被提升後int完成,看來你測試的避免了編譯器,通過轉換布爾的中間步驟,而直接推動實際bool值。

1

這是一個解釋,我沒有檢查與標準,但。 從您的實驗看來,「<」運算符未定義爲布爾值。比較的是布爾變換後的無符號整數。理論上,標準可能不保證所有「真實」的布爾值都被轉換爲相同的值。並且-1被轉換爲最大的unsigned int。

作爲另一實驗,下面的代碼

#include <iostream> 

int main() 
{ 
std::cout<< (((bool)1) == true) << "\n"; 
std::cout<< (((bool)2) == true) << "\n"; 
std::cout<< (((bool)0) == false) << "\n"; 
std::cout<< (((bool)1) == false) << "\n"; 
    return 0; 
} 

打印1 1 1 0

因此,任何非零值是 「真」。