我必须拿起Delphi来完成我正在做的最近的合同工作,而我想要澄清的一件事就是在条件语句中执行逻辑,例如if
.
我来自C/C++和这些语言的背景,一旦if
声明失败,其余的逻辑就不会被执行.例如:
if (somefunc() == FALSE && anotherfunc() == TRUE)
Run Code Online (Sandbox Code Playgroud)
在上述情况下,如果somefunc()
回报率TRUE
则anotherfunc()
不会被调用.
从目前为止我所看到的Delphi中,这并不成立.相反,为了
if (somefunc() = False and anotherfunc() = True) then
Run Code Online (Sandbox Code Playgroud)
那么,无论什么somefunc()
回报,anotherfunc()
都会被召唤.
我已经阅读了各种Delphi书籍,并重读了一些有条件的章节,并且在任何地方都找不到这种行为.任何人都能指出我在Delphi或Pascal的某个地方,这种行为是什么?
Dav*_*nan 21
该文档的链接在这里:
布尔短路评估
Type Switch Syntax {$B+} or {$B-} {$BOOLEVAL ON} or {$BOOLEVAL OFF} Default {$B-} {$BOOLEVAL OFF} Scope Local$ B指令在和/或布尔运算符的两个不同的Delphi代码生成模型之间切换.
在{$ B +}状态下,编译器生成用于完整布尔表达式求值的代码.这意味着,即使已知整个表达式的结果,也可以保证评估从and和or运算符构建的布尔表达式的每个操作数.
在{$ B-}状态下,编译器生成用于短路布尔表达式求值的代码,这意味着一旦整个表达式的结果从左到右的评估顺序变得明显,评估就会停止.
如您所见,默认选项用于短路评估.
不幸的是,你的测试中有点混淆了.事实上,您的Delphi代码与C代码完全不同.
if (somefunc() == FALSE && anotherfunc() == TRUE) // C code
if (somefunc() = False and anotherfunc() = True) then // Delphi code
Run Code Online (Sandbox Code Playgroud)
在Delphi中,and
运算符的优先级高于相等运算符=
.这意味着您的Delphi代码相当于:
if (somefunc() = (True and anotherfunc()) = True) then
Run Code Online (Sandbox Code Playgroud)
但在C和C++中,优先级是另一种方式.因此,&&
具有较低的优先级比==
.因此,无论短路评估如何,您问题中的Delphi和C++ if语句在逻辑上都是不同的.
我很确定你真的打算像这样写你的Delphi代码:
if ((somefunc() = False) and (anotherfunc() = True)) then
Run Code Online (Sandbox Code Playgroud)
这将提供与C++代码相同的逻辑,并且由于短路评估,您会看到相同的行为.
最后,你永远不应该对测试False
和True
德尔福.总是写这样的代码:
if not somefunc() and anotherfunc() then
Run Code Online (Sandbox Code Playgroud)
如果您的函数anotherfunc()
在此代码上被调用
if (somefunc() = False and anotherfunc() = True) then
Run Code Online (Sandbox Code Playgroud)
那么你已经设置了 BOOLEVAL ON
正如大卫指出的,编译器首先评估 False and anotherfunc()
在BOOLEVAL OFF
编译器知道的模式下,这False and AnyBoolState
将导致False
并因此anotherfunc()
不被调用(实际上它永远不会被调用)。
作为一个简单的测试,我扩展了 jachagate 程序来显示你的表情
program AndEvaluation;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
function FalseFunc( const AName : string ) : Boolean;
begin
Write( AName, '(False)', '-' );
Result := False;
end;
function TrueFunc( const AName : string ) : Boolean;
begin
Write( AName, '(True)', '-' );
Result := True;
end;
begin
try
// (somefunc() = False and anotherfunc() = True)
//
// in this testcase translated to:
//
// somefunc() => FalseFunc( 'First' )
// False => FalseFunc( 'Second' )
// anotherfunc() => TrueFunc( 'Third' )
// True => TrueFunc( 'Fourth' )
{$B+}
Writeln( 'BOOLEVAL ON' );
if ( FalseFunc( 'First' ) = FalseFunc( 'Second' ) and TrueFunc( 'Third' ) = TrueFunc( 'Fourth' ) )
then
Writeln( 'True' )
else
Writeln( 'False' );
{$B-}
Writeln( 'BOOLEVAL OFF' );
if ( FalseFunc( 'First' ) = FalseFunc( 'Second' ) and TrueFunc( 'Third' ) = TrueFunc( 'Fourth' ) )
then
Writeln( 'True' )
else
Writeln( 'False' );
except
on E : Exception do
Writeln( E.ClassName, ': ', E.Message );
end;
ReadLn;
end.
Run Code Online (Sandbox Code Playgroud)
现在让我们看看结果
BOOLEVAL ON
Second(False)-Third(True)-First(False)-Fourth(True)-True
BOOLEVAL OFF
First(False)-Second(False)-Fourth(True)-True
Run Code Online (Sandbox Code Playgroud)
正如输出解释了在调用之前调用BOOLEVAL ON
您的anotherfunc()
遗嘱。 somefunc()
随着BOOLEVAL OFF
你anotherfunc()
是永远不会被调用。
如果你想拥有相同的
if (somefunc() == FALSE && anotherfunc() == FALSE)
Run Code Online (Sandbox Code Playgroud)
你必须像这样翻译它
if ( somefunc() = False ) and ( anotherfunc() = False ) then
Run Code Online (Sandbox Code Playgroud)
或者更好更短的方式
if not somefunc() and not anotherfunc() then
Run Code Online (Sandbox Code Playgroud)
或者甚至更短
if not( somefunc() or anotherfunc() ) then
Run Code Online (Sandbox Code Playgroud)
但是为了避免anotherfunc()
每次必须设置时都被调用BOOLEVAL OFF
归档时间: |
|
查看次数: |
4684 次 |
最近记录: |