布林 (資料類型)

真理和谬误的基本计算表示

布林(英語:Boolean)是計算機科學中的邏輯數據類型,以發明布林代數的數學家喬治·布爾為名。它是只有兩種值的原始類型,通常是。布爾數據類型主要與條件語句相關聯,條件語句通過根據開發人員指定的條件式,更改程序控制流來允許評估語句的運算值為真或假(即條件成立或不成立))。這是一種更廣泛的邏輯數據類型的特殊情況(參見概率邏輯)-邏輯並不總是只屬於布爾類型的。

「布林」的各地常用名稱
中國大陸布爾
臺灣布林
港澳布林

在一些語言中,布爾數據類型被定義為可代表多於兩個真值。例如,ISO SQL:1999標準定義了一個SQL布爾型可以儲存三個可能的值:真、假、未知(SQL null被當作未知真值來處理,但僅僅在布爾型中使用)。在此情況下,未知先於真及假,因為布爾型一開始是未有實際值,其值是unknown(也有機會是隨機值)而非真。

Ada

Ada在標準包中定義Boolean為一種枚舉類型,有兩種值FalseTrue,並且False < True

type Boolean is (False, True);
 
p : Boolean := True;
...
if p then
  ...
end if;

相關的操作(=, /=, <, <=, >, >=)使用語所有的枚舉類型,包括Boolean。布爾運算and, or, xornotBoolean及任意聲明的子類型定義。布爾運算也適用於Boolean值數組。

Algol

Algol 60Boolean數據類型和相關的操作,定義在Algol 60報告中。這在ALGOL 68中被簡化為bool[1]

ALGOL 68語言詳細說明(177頁)中關於布爾操作定義的原文:

10.2.2. 布爾操作數的運算

  1. op ? = (bool a, b) bool:( a | true | b );
  2. op ? = (bool a, b) bool: ( a | b | false );
  3. op ? = (bool a) bool: ( a | false | true );
  4. op = = (bool a, b) bool:( a?b ) ? ( ?b??a );
  5. op ≠ = (bool a, b) bool: ?(a=b);
  6. op abs = (bool a)int: ( a | 1 | 0 );

C

C99之前,C語言的標準沒有提供布爾類型,但是這不意味着C90不能表示布爾值的概念。C中的所有布爾運算(&&, ||)以及條件聲明(if, while)都以非零值代表,零值代表。這樣,在其他類型如一個整數或一個枚舉中保存布爾值就變得很平常。為了方便,常常為布爾類型創建一個typedef來和一些已存在的數據類型相關聯。C99標準也提供了一個內置的布爾類型。

為了說明C中的布爾型,注意以下C代碼:

if (my_variable) {
  printf("True!\n");
} else {
  printf("False!\n");
}

等價於:

if (my_variable != 0) {
  printf("True!\n");
} else {
  printf("False!\n");
}

簡單來說這就是一個整數類型。由於C標準要求0用在指針上下文中時要代表空指針,上面的概念也可以用來檢查一個指針是否為空,雖然一些程序風格不建議這樣用。這種情況同樣適用於浮點值,當比較它們的時候要特別小心,因為它們通常包含四捨五入的結果。通常,整型用來包含布爾變量。

雖然為了測試一個變量的真假值時沒必要來命名真或假,但是在給它們分配值的時候卻是需要的。(一種方法是使用零值和一,這樣做的好處是語言獨立。)其他方法,enum關鍵字允許在語言中根據你的選擇來命名元素,例如:

typedef enum { FALSE, TRUE } boolean;
...
boolean b;

如下典型的預處理宏經常被使用。

#define FALSE 0
#define TRUE 1
...
int f = FALSE;

有時TRUE可能被定義為-1或~0(位運算0的補)。這意味着在現在常見的二補數計算機架構的整型中所有的位都被設置為1。

但是,在C中任意非零值都代表真就帶來了問題,因為TRUE由一個特定的值來表示,因此在其他語言中if (foo == TRUE) ...只不過是多餘的,而在C中,就是錯誤的代碼。

C99中有bool類型,取值為truefalse,定義在<stdbool.h>頭文件中:

#include <stdbool.h>
bool b = false;
...
b = true;

C++

C++編程語言在其標準化過程中引入了booltruefalse關鍵字,增加了原生數據類型來支持布爾數據,其大小被實現定義。[2] bool在1993年被引入。[3].

1998年的C++標準庫定義了一個vector<bool>類別的特例。為了優化空間,其中的元素被打包,使得每一個布爾變量只使用一位內存。這被認為是一個錯誤。vector<bool>不符合STL容器的需要。例如一個container<T>::reference必須為T類型的一個真值左值。這和vector<bool>的情況不同。類似地,vector<bool>::iterator在解除引用時不產生一個bool&。在C++標準委員會和庫工作組之間有個共識,就是vector<bool>應該被反對或完全從下一個標準中被移除。[4][5]

C#

C#中,布爾變量通過保留字bool來識別,這個保留字是預定義結構類型System.Boolean的別名,占一字節。在bool和其他類型之間不存在標準的轉換。此語言還提供了一個布爾類型DBbool,可以表示三種值:truefalsenull。這和SQL中布爾表達式的用法類似。[6]

輸出一個布爾型的代碼如下:

bool myBool = (i == 5);
System.Console.WriteLine(myBool ? "I = 5" : "I != 5");

Fortran

Fortran被標準化之前,於1950年代引入了LOGICAL關鍵字和相關的操作.NOT..AND..OR.等等。

logical :: bool        ! 宣告一個布林變數名稱為bool
bool=.true.            ! 將變數bool存入值.true.
if (bool) then         ! 由於條件為.true.所以進入內部執行
  print*,"bool=",bool  ! 顯示 bool=T
  bool=1==2            ! 1==2的運算結果是.false.,將.false.存入變數bool
  print*,"bool=",bool  ! 再次顯示,這時候變成 bool=F
end if

Java

Java語言中,布爾變量由原始類型boolean表示。Java虛擬機將實際在內存中的表現抽象,這樣JVM開發者可以使用儘可能方便的方式來代表布爾量(例如,一個字節或者一個)。

Java語言規範不允許任何顯式或隱式的從boolean轉換。這樣就需要編譯器拒絕如下代碼:

int i = 1;
if (i)
  System.out.println("i is not zero.");
else
  System.out.println("i is zero.");

因為整型變量i不能轉換為一個布爾型並且if語句需要一個boolean條件。[7]

在Java中,boolean值(和其他原始類型相同)可以被附加到字符串。這個特性提供了一個默認的布爾型的可視化表現(true被顯示為"true",false被顯示為"false")。[7]

JavaScript

JavaScript有兩個關鍵字,truefalse,兩者都為小寫。JavaScript是一種弱類型的語言,沒有明確的布爾數據類型供其變量使用。但是許多值用在邏輯上下文時可以被當成false,包括0)、null、零長度字符串("")、NaN以及undefined。所有其他變量值,包括1)、空數組和空對象,都被認為是trueJavaScript 提供了一個Boolean 對象,可以被用作控制布爾值的容包裝。

var boolean = true;    //設boolean為true

if(boolean && 1){
    console.log("This is true.");    //將會顯示這個,因為boolean是true和1亦是true
}else{
    console.log("This is false.");
}

但如果使用Boolean物件的話,它總是會被當成true,儘管其包含false值。

var boolean = new Boolean(false);    //設boolean為一個Boolean物件,並設定其內容為false

if(boolean){
    console.log("This is true.");    //將會顯示這個,因為Boolean物件不是null
}else{
    console.log("This is false.");
}

若僅使用 Boolean() function,則視同將參數轉為布林值

var boolean = Boolean(false);    //等同於將 boolean 設為 false

if(boolean){
    console.log("This is true.");    
}else{
    console.log("This is false."); //將會顯示這個,因為 boolean 的值為 false
}

由於JavaScript的歷史兼容性和隱性類型轉換,空數組([])、字符「0」的字符串("0")、水平制表字符的字符串("\t")互為不寬鬆等同(!=),但都寬鬆等同(==)於數字0(0),被形容為「JavaScript的三位一體」的迷因。

λ演算

λ演算計算模型中,布爾型由Church數表示。

Lisp

LISP有兩個特殊的符號TNIL,分別代表了邏輯值真和假。但是,任意非NIL值都由LISP系統翻譯成真。特殊的符號NIL也用空列表()表示。因此空列表為假,但是任何有數據的列表都為真。這樣,什麼都沒有為假,其他所有都為真。

ML

和Ocaml類似,ML語言擁有bool類型,包含truefalse值,例如:

- fun isittrue x = if x then "YES" else "NO" ;
> val isittrue = fn : bool -> string
- isittrue true;
> val it = "YES" : string
- isittrue false;
> val it = "NO" : string
- isittrue (8=8);
> val it = "YES" : string
- isittrue (7=5);
> val it = "NO" : string

Objective-C

Objective-C提供了BOOL類型,以及宏YESNO。由於Objective-C是C語言的超集,因此C語言的布爾語義也適用。

Swift

Swift的布林型別是 Bool,主要用於 if 和 while 的條件判斷,值只能是真true或假false

let isSuccess = true
let isOpenDoor = false

Ocaml

Ocaml 擁有一個 bool 值,為 truefalse

# 1 = 1 ;;
- : bool = true

和很多其它的語言一樣,Ocaml使用 truefalse關鍵字來表示布林值。

Pascal

BooleanPascal提供的基本數據類型,定義和用法如下:

(* 系统或标准声明 *)
Type 
   Boolean = (False,True);

(* 用法 *)
var
  value: Boolean;
 
...
 
value := True;
value := False;
 
if value then
begin
  ...
end;

枚舉外的值沒有被定義。某些編譯器實現(如Delphi)為了接口目的擁有特殊的擴展布爾類型,並將其映射到C數值類型上,例如bytebool、wordbool、longbool等。

參考文獻

  1. ^ Report on the Algorithmic Language ALGOL 68, Section 10.2.2. (PDF). Aug 1968 [2007 Apr]. (原始內容存檔 (PDF)於2012-07-17). 
  2. ^ Working Paper for Draft Proposed International Standard for Information Systems-- Programming Language C++. Dec 1996 [2007 May]. (原始內容存檔於2016-03-04). 
  3. ^ Evolving a language in and for the real world: C++ 1991-2006 (PDF). 2007 [2008 March]. (原始內容存檔 (PDF)於2007-11-20). 
  4. ^ vector<bool>: More Problems, Better Solutions (PDF). Aug 1999 [2007 May]. (原始內容存檔 (PDF)於2012-08-31). 
  5. ^ A Specification to deprecate vector<bool>. Mar 2007 [2007 May]. (原始內容存檔於2012-08-31). 
  6. ^ C# Language Specifications: Database boolean type. Microsoft Development Network. [2014-02-24]. (原始內容存檔於2016-05-09) (英語). 
  7. ^ 7.0 7.1 Java Language and Virtual Machine Specifications. ORACLE. [2014-02-24]. (原始內容存檔於2009-02-26) (英語).