首页 > 解决方案 > 为什么“如果不是”不适用于多个“或”语句

问题描述

代码如下:

procedure TForm1.dxBarButton1Click(Sender: TObject);
begin
  if not (dxStatusBar1.Panels[0].Text = 'Johnny') or (dxStatusBar1.Panels[0].Text = 'Stephen') then begin
    ShowMessage('Not for you.');
    abort;
  end else begin
    Form8 :=TForm8.Create(nil);
    try
      Form8.ShowModal;
    finally
      Form8.Free;
    end;
  end;
end;

但是,当显示的文本是“斯蒂芬”时,我仍然会收到“不适合你”的消息。?? 为什么代码没有区别?

标签: delphi

解决方案


if not (dxStatusBar1.Panels[0].Text = 'Johnny') or (dxStatusBar1.Panels[0].Text = 'Stephen') then

if .. then条件语句的一部分。条件是

not (dxStatusBar1.Panels[0].Text = 'Johnny') or (dxStatusBar1.Panels[0].Text = 'Stephen')

这是一个表达式。现在,根据运算符优先级的 Pascal 规则not具有比 更高的优先级or,因此表达式解析如下:

(not (dxStatusBar1.Panels[0].Text = 'Johnny'))
  or
(dxStatusBar1.Panels[0].Text = 'Stephen')

这相当于

(dxStatusBar1.Panels[0].Text <> 'Johnny')
  or
(dxStatusBar1.Panels[0].Text = 'Stephen')

也就是说,该陈述是True 当且仅当下列陈述之一为真:

  1. 文字不是'Johnny'
  2. 文字是'Stephen'

因此,如果文本是'Johnny',则两个语句都是错误的,并且表达式的计算结果为False。另一方面,如果文本不是'Johnny',则第一个语句是True,所以整个析取True

换句话说,表达式可以简单地写成

dxStatusBar1.Panels[0].Text <> 'Johnny'.

实现这一点的更简单方法:如果第一个析取项是False(即,如果名称 'Johnny'),那么显然第二个析取项是False,因此可以省略。

你想要的是

not
(
  (dxStatusBar1.Panels[0].Text = 'Johnny')
    or
  (dxStatusBar1.Panels[0].Text = 'Stephen')
)

根据德摩根定律,可以写成

not (dxStatusBar1.Panels[0].Text = 'Johnny')
  and
not (dxStatusBar1.Panels[0].Text = 'Stephen')

(回忆 的not优先级高于and),或者等价地,

(dxStatusBar1.Panels[0].Text <> 'Johnny')
  and
(dxStatusBar1.Panels[0].Text <> 'Stephen')

推荐阅读