帕斯卡集很奇怪

use*_*072 2 delphi pascal

我不明白为什么这段代码不能正常工作:

program selection;
var 
    n : integer;
begin
    readln(n);
    if (n in [100..1000]) then writeln('Selected!');
    readln;
end.
Run Code Online (Sandbox Code Playgroud)

这对我来说很好,值在1到233之间,如果我输入233或更多,则不会执行writeln .. 这很奇怪.我也尝试过其他值,结果或多或少相同,唯一不同的是它失败的值.

Rob*_*edy 13

Delphi设置最多只能达到255; 最大值为1000的集合不起作用.我编译的代码有点惊讶.

当截断为8位时,值1000为232,这解释了为什么大于该值的值失败.

相反,你可以使用该InRange功能; 它使用闭合范围就像set constructors一样.

if InRange(n, 100, 1000) then ...
Run Code Online (Sandbox Code Playgroud)

您还可以使用普通的旧不等式运算符来测试值是否位于给定范围内:

if (100 <= n) and (n <= 1000) then ...
Run Code Online (Sandbox Code Playgroud)

最后,您可以使用case声明.大小写语句选择器不是集合,因此它们不受与集合相同的规则约束.

case n of
  100..1000: begin ... end;
end;
Run Code Online (Sandbox Code Playgroud)

缺点是当只有一个案例分支时,它看起来有点笨拙.

  • `InRange(n,100,1000)`是我在if语句中执行此操作的方式.在`Math`单元中定义. (3认同)

Dav*_*nan 6

Rob解释了为什么你不能使用Delphi集合来满足你的需求.我还要强调a set是一种非常重量级的类型来存储等于间隔的数量.一旦识别出这一点,就可以使用一个InRange按时间间隔运行的函数.

作为一个有趣的练习,您可以编写一个代表间隔的简单记录.然后,您可以使用运算符重载来实现in将测试间隔包含的运算符.这允许您使用可读符号,并具有间隔的自然存储.当然,元素大小没有限制.

这是简单的演示:

{$APPTYPE CONSOLE}

type
  TInterval = record
  public
    Low: Integer;
    High: Integer;
  public
    class operator In(const Value: Integer; 
      const Interval: TInterval): Boolean; inline;
  end;

class operator TInterval.In(const Value: Integer; 
   const Interval: TInterval): Boolean;
begin
  Result := (Value>=Interval.Low) and (Value<=Interval.High);
  // or implement with a call to Math.InRange()
end;

function Interval(Low, High: Integer): TInterval; inline;
begin
  Result.Low := Low;
  Result.High := High;
end;

begin
  Writeln(25 in Interval(10, 100));
  Writeln(125 in Interval(10, 100));
  Writeln(2500 in Interval(1000, 10000));
  Writeln(12500 in Interval(1000, 10000));
  Readln;
end.
Run Code Online (Sandbox Code Playgroud)