Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 德尔福';和';有两个条件的评估_Delphi - Fatal编程技术网

Delphi 德尔福';和';有两个条件的评估

Delphi 德尔福';和';有两个条件的评估,delphi,Delphi,我最近正在做一项合同工作,我必须学习Delphi,我希望有人澄清的一件事是在条件语句中执行逻辑,例如if 我有C/C++的背景,在这些语言中,只要知道语句失败,其余的逻辑就不会执行。例如: if (somefunc() == FALSE && anotherfunc() == TRUE) 在上述情况下,如果somefunc()返回TRUE,则永远不会调用anotherfunc() 在德尔菲,从我目前所看到的情况来看,这并不成立。相反,对于 if (somefunc() = Fa

我最近正在做一项合同工作,我必须学习Delphi,我希望有人澄清的一件事是在条件语句中执行逻辑,例如
if

我有C/C++的背景,在这些语言中,只要知道
语句失败,其余的逻辑就不会执行。例如:

if (somefunc() == FALSE && anotherfunc() == TRUE)
在上述情况下,如果
somefunc()
返回
TRUE
,则永远不会调用
anotherfunc()

在德尔菲,从我目前所看到的情况来看,这并不成立。相反,对于

if (somefunc() = False and anotherfunc() = True) then
然后,无论
somefunc()
返回什么,都将调用另一个
somefunc()

我读过各种Delphi书籍,重读了一些有条件的章节,在任何地方都找不到关于这种行为的提及。有人能告诉我在德尔福或帕斯卡的某个地方有这种行为吗?

布尔短路评估 在Delphi中,
运算符比相等运算符
=
具有更高的精度。这意味着您的Delphi代码相当于:

if (somefunc() = (True and anotherfunc()) = True) then
<>但是在C和C++中,优先级是另一种方式。所以
&&
=
更重要。因此,在你的问题中,Delphi和C++的if语句逻辑上是不同的,不管短路评估。 我很确定您真的打算这样编写Delphi代码:

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

这将给出与C++代码相同的逻辑,并且由于短路评估,您将看到相同的行为。

最后,您不应该在Delphi中测试
False
True
。始终按照以下方式编写代码:

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

如果您的函数
anotherfunc()
在此代码上被调用

if (somefunc() = False and anotherfunc() = True) then
然后您已将
布尔值设置为ON

正如David指出的,编译器首先计算
False和另一个func()

BOOLEVAL OFF
模式下,编译器知道
False和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
正如输出解释的那样,在调用
somefunc()
之前,您的
另一个func()
将被调用

关闭
BOOLEVAL
时,您的
另一个func()
永远不会调用

如果你想和我一样

if (somefunc() == FALSE && anotherfunc() == FALSE)
你必须这样翻译

if ( somefunc() = False ) and ( anotherfunc() = False ) then
还是更好更短的方法

或者更短

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

但是,为了避免每次必须关闭
BOOLEVAL时调用
anotherfunc()
,为了避免不调用函数,可以这样做:

  bool_somefunc := (somefunc() = 42);
  bool_anotherfunc := (anotherfunc() = 17);
  if ( (bool_somefunc = False) and (bool_anotherfunc = True) ) then
这确保每个functon都被称为short eval
打开或关闭。

签出-“允许但不要求短路”。您不需要写入布尔状态,即
=False
=True
。相反,您可以使用
not
运算符检查if语句是否为false,方法是在if语句中不包含
not
,例如,true而不是false。根据您希望对Delphi代码的解释方式,当somefunc返回false时,应调用另一个func,但是你说这是个问题。很抱歉,上面的示例代码是错误的。显然,您遗漏了一些括号,因此编译器将尝试计算“FALSE和anotherfunc()”,而不知道如何处理“somefunc()”和“True”。不管怎样,我明白你的观点,也理解你的问题,只是说了这句话后我感觉好多了。+1就你最后一句话而言,我希望我能做另一句话来解释根本的问题。我经常在Delphi和VS之间切换,这总是让我感到……我要么在C#中添加括号,要么在Delphi中忘记括号,然后马上给自己一记耳光。@J。。。是的,我也一直在努力解决这个问题。我总是在我的C#代码中有额外的参数,因为我永远记不起运算符的优先级。答案很好。仔细想想,
somebool和anotherbool
是一个有效的布尔语句,但是
somebool和somevalue=something
并不能强迫您在布尔值周围添加括号。@nrjohnstone好吧,
If
需要一个计算结果为
boolean
的表达式。如果有一个函数返回一个
布尔值
,那么它已经是一个计算结果为
布尔值
的表达式了。对照
True
False
进行测试显然是多余的。这样做会让你进入地狱,正如你所发现的那样。您可能来自不包含真正布尔类型的旧版本C的背景。Delphi是不同的。+1这一点,问题中出现的“即使somefunc返回False”告诉我,询问者正在运行的实际代码是
如果(somefunc()=True和anotherfunc()=True),那么
@DavidHeffernan Yes,如果设置了
BOOLEVAL OFF
,那么这将是唯一的可能性:o)让我们等待OP反应……事实上,很难想象询问者设置BOOLEVAL的效果。
  bool_somefunc := (somefunc() = 42);
  bool_anotherfunc := (anotherfunc() = 17);
  if ( (bool_somefunc = False) and (bool_anotherfunc = True) ) then