帕斯卡集很奇怪

时间:2013-03-28 12:43:12

标签: delphi pascal

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

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

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

2 个答案:

答案 0 :(得分:13)

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

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

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

if InRange(n, 100, 1000) then ...

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

if (100 <= n) and (n <= 1000) then ...

最后,您可以使用case语句。案例陈述选择器不是集合,因此它们不受集合规则的约束。

case n of
  100..1000: begin ... end;
end;

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

答案 1 :(得分:6)

Rob has explained为什么你不能使用Delphi集合来满足你的需要。我还要强调,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.