布尔 (数据类型)

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

布尔(英语:Boolean)是计算机科学中的逻辑数据类型,以发明布尔代数的数学家乔治·布尔为名。它是只有两种值的原始类型,通常是。布尔数据类型主要与条件语句相关系,条件语句通过根据开发人员指定的条件式,更改程序控制流来允许评估语句的运算值为真或假(即条件成立或不成立))。这是一种更广泛的逻辑数据类型的特殊情况(参见概率逻辑)-逻辑并不总是只属于布尔类型的。

“布尔”的各地常用名称
中国大陆布尔
台湾布林
港澳布林

在一些语言中,布尔数据类型被定义为可代表多于两个真值。例如,ISO SQL:1999标准定义了一个SQL布尔型可以储存三个可能的值:真、假、未知(SQL null被当作未知真值来处理,但仅仅在布尔型中使用)。在此情况下,未知先于真及假,因为布尔型一开始是未有实际值,其值是unknown(也有机会是随机值)而非真。

Ada在标准包中定义Boolean为一种枚举类型,有两种值FalseTrue,并且False < True

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

相关的操作(=, /=, <, <=, >, >=)使用语所有的枚举类型,包括Boolean。布尔运算and, or, xornotBoolean及任意声明的子类型定义。布尔运算也适用于Boolean值数组。

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 );

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++编程语言在其标准化过程中引入了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#中,布尔变量通过保留字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语言中,布尔变量由原始类型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有两个特殊的符号TNIL,分别代表了逻辑值真和假。但是,任意非NIL值都由LISP系统翻译成真。特殊的符号NIL也用空列表()表示。因此空列表为假,但是任何有数据的列表都为真。这样,什么都没有为假,其他所有都为真。

和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的布尔类型是 Bool,主要用于 if 和 while 的条件判断,值只能是真true或假false

let isSuccess = true
let isOpenDoor = false

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) (英语).