Delphi 'AND'评价,有2个条件

xvw2m8pv  于 2022-11-04  发布在  其他
关注(0)|答案(3)|浏览(245)

我不得不为我正在做的一个最近的合同工作拿起 Delphi ,我希望有人澄清的一件事是在一个条件语句(如if)中执行逻辑。
我有C/C++的背景,在这些语言中,一旦if语句失败,其余的逻辑就不会执行。例如:

if (somefunc() == FALSE && anotherfunc() == TRUE)

在上面的例子中,如果somefunc()返回TRUE,则永远不会调用anotherfunc()
在 Delphi 斐,从我目前所看到的情况来看,这并不成立。

if (somefunc() = False and anotherfunc() = True) then

则不管somefunc()返回什么,都将调用anotherfunc()
我读过很多 Delphi 的书,也重读了一些关于条件的章节,但在任何地方都找不到这种行为的描述,谁能告诉我在Delphi或Pascal中哪里有这种行为的描述?

kmb7vmvb

kmb7vmvb1#

documentation link is here

布尔短路评估

| 型号|切换|
| - -|- -|
|语法|{$B+}或{$B-} {$BOOLEVAL开}或{$BOOLEVAL关}|
|预设值|{$B-} {$BOOLEVAL关闭}|
|范围| 本地|
$B指令在以及布尔运算符的两种不同的 Delphi 代码生成模型之间切换。
在{$B+}状态下,编译器会产生程式码以完成布林运算式的评估。这表示从and和or运算子建立的布林运算式的每一个算子都保证会被评估,即使整个运算式的结果已经知道。
在{$B-}状态下,编译器生成用于短路布尔表达式求值的代码,这意味着一旦整个表达式的结果以从左到右的求值顺序变得明显,求值就立即停止。
如您所见,默认选项用于短路评估。
不幸的是,你在测试中有点搞混了。你的 Delphi 代码实际上与C代码有很大的不同。
第一个
在 Delphi 中,and运算符的优先级高于等于运算符=。这意味着您的Delphi代码等效于:

if (somefunc() = (True and anotherfunc()) = True) then

但是在C和C中,优先级是相反的,所以&&的优先级是lower precedence,而不是==,所以你的问题中的 Delphi 和C if语句在逻辑上是不同的,不管短路求值。
我很确定您确实想这样编写 Delphi 代码:

if ((somefunc() = False) and (anotherfunc() = True)) then

这将给予与C++代码相同的逻辑,并且由于短路求值,您将看到相同的行为。
最后,永远不要在 Delphi 中对FalseTrue进行测试。

if not somefunc() and anotherfunc() then
5n0oy7gb

5n0oy7gb2#

如果函数anotherfunc()在此代码中被调用

if (somefunc() = False and anotherfunc() = True) then

那么您已经设置了BOOLEVAL ON
正如大卫指出的编译器首先求出False and anotherfunc()
BOOLEVAL OFF模式下,编译器知道False and AnyBoolState将导致False,因此不会调用anotherfunc()(事实上,它永远不会被调用)。
作为一个简单的测试,我扩展了jachaguate程序来显示您的表达式

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.

现在让我们来看看结果

BOOLEVAL ON
Second(False)-Third(True)-First(False)-Fourth(True)-True

BOOLEVAL OFF
First(False)-Second(False)-Fourth(True)-True

如输出所示,BOOLEVAL ON将在调用**somefunc()之前**调用您的anotherfunc()
对于BOOLEVAL OFF,您的anotherfunc()永远不会被调用。
如果您想拥有与

if (somefunc() == FALSE && anotherfunc() == FALSE)

你得这样翻译

if ( somefunc() = False ) and ( anotherfunc() = False ) then

或者更好更短的方式

if not somefunc() and not anotherfunc() then

或者更短

if not( somefunc() or anotherfunc() ) then

但为了避免每次必须设置BOOLEVAL OFF时都调用anotherfunc()

nuypyhwy

nuypyhwy3#

若要避免不调用函数,您可以这样做:

bool_somefunc := (somefunc() = 42);
  bool_anotherfunc := (anotherfunc() = 17);
  if ( (bool_somefunc = False) and (bool_anotherfunc = True) ) then

这确保了无论是打开还是关闭short eval,都调用每个函数。

相关问题