我不明白为什么这段代码不能正常工作:
program selection;
var
n : integer;
begin
readln(n);
if (n in [100..1000]) then writeln('Selected!');
readln;
end.
这对我来说适用于 1 到 233 之间的值,如果我输入 233 或更多,writeln.. 不会被执行。这很奇怪。我也尝试过其他值,结果或多或少相同,唯一不同的是它失败的值。
Delphi 集最多只能达到 255 个;最大值为 1000 的集合不起作用。我对您编译的代码感到有些惊讶。
当截断为 8 位时,值 1000 为 232,这解释了为什么大于该值的值会失败。
相反,您可以使用该InRange
功能;它像集合构造函数一样使用封闭范围。
if InRange(n, 100, 1000) then ...
您还可以使用普通的旧不等式运算符来测试该值是否在给定范围内:
if (100 <= n) and (n <= 1000) then ...
最后,您可以使用case
语句。案例语句选择器不是集合,因此它们不受与集合相同的规则的约束。
case n of
100..1000: begin ... end;
end;
缺点是当只有一个 case 分支时,它看起来有点笨拙。
Rob 解释了为什么你不能使用 Delphi 集来满足你的需要。我还要强调 aset
是一种非常重量级的类型,用于存储相当于间隔的内容。一旦认识到这一点,就可以使用类似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.