为什么 'if not' 没有应用在多个 'or' 语句中

why 'if not' is not applying in multiple 'or' statement

代码是这样的:

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;

但是,当显示的文本为 'Stephen' 时,我仍然收到消息 'Not for you.' ?? 为什么代码不区分?

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

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

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

这是一个表达式。现在,根据 Pascal rules of operator precedencenot 的优先级高于 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 iff下列陈述中至少有一项为真:

  1. 文本不是 'Johnny'
  2. 正文是'Stephen'.

因此,如果文本为 'Johnny',则两个语句均为假且表达式的计算结果为 False。另一方面,如果文本不是 'Johnny',则第一个语句是 True,因此整个 disjunctionTrue.

也就是说,表达式可以简单地写成

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

一个更简单的实现方式:如果第一个析取符是False(也就是说,如果名字'Johnny'),那么显然第二个分离符是 False,因此可以省略。

你想要的是

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

根据De Morgan's laws可以写成

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')