簡體   English   中英

布爾值的排序

[英]Ordering of boolean values

下C ++或<stdbool.h>從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 ++代碼,編譯為C代碼的GCC 4.6.3-ubuntu5和編譯為C ++代碼的G ++ 4.6.3-1ubuntu5,所有你得到的是

false < true

也就是說,以下不等式都是false

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

以下是true

false < true

在C ++中(我也懷疑在C語言中), bool的比較完全如同false0true1 如果類型是bool ,則除了truefalse之外的值都不可能。

bool與其他數值類型進行比較時,它將轉換為int ,同樣將false轉換為0並將true轉換為1

編輯: C99中的C ++和stdbool.h也強制布爾值為0(假)或1(真) - bool b = -1; b的值設置為1.由於1 < 11 < 0都是假的,因此問題中的不等式是正確的。

編輯:(由詹姆斯)除了上面的編輯不是真的正確,至少對於C ++。 bool的值不是0或1,它的值為falsetrue 只有當它被提升為int ,轉換才會創建01的值。

正如康拉德指出的那樣,沒有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

這很有道理。 積分類型=> bool轉換實際上是b = i != 0 為了進行<比較,它通過規則false => 0和true => 1將bool提升為int。 在你的第一種情況下, -1將等於true,並且兩者都將提升為1,因此它是錯誤的。 顯然,對於第二和第三種情況,1永遠不會小於0,而在最后一種情況下0 < 1

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

實際比較(我相信)是在bool升級后在int完成的,看來你測試的編譯器避免了通過bool轉換的中間步驟,只是提升了實際的bool值。

operator>和<基於此:

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

這個假:(bool)-1 <true(bool)-1 <false因為bool中的滾動算術b = -1;

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

此外,將-1與無符號數進行比較會使-1轉換為無符號,並且在您的平台上會導致整數溢出,從而產生UINT_MAX(或者類型為bool的類型)。 這現在解釋了為什么以下表達式是錯誤的:

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

對於C ++,只是false < true

因為C更難回答。 我知道了

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

似乎,如果編譯器支持_Bool ,它就像在C ++中一樣工作並自動轉換為0/1,但如果不是,它應該作為char工作,它將是b < trueb < false如果char被簽名

對於我(int)(bool)-1即使在C中也是1,所以bool被定義為不是char

這是一個解釋,我沒有用標准檢查過。 從您的實驗中,似乎沒有為布爾值定義“<”運算符。 比較的是布爾值被轉換為的無符號整數。 從理論上講,標准可能無法保證所有“真正的”布爾值都轉換為相同的值。 並且-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

所以任何非零值都是“true”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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