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