The
Boolean operators not, and, or, and xor take
operands of any Boolean type and return a value of type Boolean.
Operator |
Operation |
Operand types |
Result type |
Example |
|
not |
negation |
Boolean |
Boolean |
not (C in MySet) |
|
and |
conjunction |
Boolean |
Boolean |
Done and (Total > 0) |
|
or |
disjunction |
Boolean |
Boolean |
A or B |
|
xor |
exclusive disjunction |
Boolean |
Boolean |
A xor B |
These operations are governed by standard rules of Boolean logic. For example, an expression of the form x and y is True if and only if both x and y are True.
The
compiler supports two modes of evaluation for the and and or
operators: complete evaluation and short-circuit (partial) evaluation. Complete
evaluation means that each conjunct or disjunct is evaluated, even when the
result of the entire expression is already determined. Short-circuit
evaluation means strict left-to-right evaluation that stops as soon as the
result of the entire expression is determined. For example, if the expression A
and B is evaluated under short-circuit mode when A is False,
the compiler won’t evaluate B; it knows that the entire expression is False
as soon as it evaluates A.
Short-circuit evaluation is usually preferable because it guarantees minimum execution time and, in most cases, minimum code size. Complete evaluation is sometimes convenient when one operand is a function with side effects that alter the execution of the program.
Short-circuit evaluation also
allows the use of constructions that might otherwise result in illegal runtime
operations. For example, the following code iterates through the string S, up
to the first comma.
while
(I <= Length(S)) and (S[I] <> ',') do
begin
...
Inc(I);
end;
In a case
where S has no commas, the last iteration increments I to a value which is
greater than the length of S. When the while condition is next tested,
complete evaluation results in an attempt to read S[I], which could cause a
runtime error. Under short-circuit evaluation, in contrast, the second part of
the while condition (S[I] <> ',') is not evaluated after the first
part fails.
Use the $B compiler directive to control evaluation mode. The default state is {$B-}, which enables short-circuit evaluation. To enable complete evaluation locally, add the {$B+} directive to your code. You can also switch to complete evaluation on a project-wide basis by selecting Complete Boolean Evaluation in the Compiler Options dialog.
Note: If either operand involves a variant, the compiler always performs complete evaluation (even in the {$B-} state).
布尔运算符not、and、or、xor操作任何布尔类型的操作数并返回Boolean类型的值。
运算符 |
操作 |
操作数类型 |
结果类型 |
范例 |
|
not |
否定 |
布尔型 |
Boolean |
not (C in MySet) |
|
and |
与 |
布尔型 |
Boolean |
Done and (Total > 0) |
|
or |
或 |
布尔型 |
Boolean |
A or B |
|
xor |
异或 |
布尔型 |
Boolean |
A xor B |
这些运算符遵循标准的布尔逻辑。例如表达式 x and y 为真(True)当且仅当 x 和 y 均为真(True)。
编译器对运算符and和or支持两种求值方式:完整求值和短路(局部)求值。完整求值(Complete evaluation)是指对每个联合项或单独项求值,即使整个表达式的结果已经确定。短路求值(Short-circuit)是指严格从左到右求值,一旦整个表达式的结果确定则停止求值(不检查余下的项)。例如,如果对表达式
A and B 以短路方式求值,那么当
A 为False时,编译器不会对B求值;显然,一旦对A求值得到False,就确定了整个表达式的值一定为False。对于运算符or,短路求值情况也相似,一旦对X求值为True,那么表达式 X or Y的值也就确定了,一定为True。
通常情况下,短路求值比完整求值优越,因为它保证了执行时间最短和大多数情况下的代码尺寸最小。当布尔运算的操作数是一个函数,并且该函数的执行与否影响到程序的执行时,这时使用完整求值模式比较方便。
对可能因运行时的非法操作而导致其他结果的布尔表达式结构,可以通过短路求值方式来避免。例如,下面的代码遍历字符串S,直到遇到第一个逗号:
while
(I <= Length(S)) and (S[I] <> ',') do
begin
...
Inc(I);
end;
对于S中没有逗号的情况,最后一次循环变量I增加后将大于S的长度。当测试下一次while条件时,完整布尔求值将试图读取S[I],这将导致运行时错误。而在短路布尔求值方式下,对于相同的情况,在while条件的第一部分失败,即表达式(I
<= Length(S))的值为False之后,while条件的第二部分(S[I]
<> ',')将不再被求值,因此不会导致错误。
在Object Pascal中,通过编译指示 $B 可以控制布尔求值模式。该编译指示的缺省状态是 {$B-},此时表示短路检查有效而不会对布尔表达式进行完整求值。要使完整布尔求值有效,只需要在代码中添加编译指示 {$B+}。也可以在编译器选项(Compiler Options)对话框(菜单Project | Options)中通过选中或不选中“完整布尔求值”(Complete Boolean Evaluation)来切换项目范围内的布尔求值方式。
注意:如果布尔表达式中的某个操作数是变体(variant)类型,那么编译器将总是对其进行完整求值,即使在编译指示 {$B-} 的状态中。
编者注
在上面的布尔运算符表中,“布尔型”是泛指任何布尔类型,包括Boolean类型;而Boolean类型是特指由Object Pascal预定义的布尔类型。在原文中也分别以常规字体Boolean和斜体Boolean作为区别。与此情况类似的是,整数类型(泛指)和Integer类型,字符串类型(泛指)和String类型等。