我不明白为什么这段代码不能正常工作:
program selection;
var
n : integer;
begin
readln(n);
if (n in [100..1000]) then writeln('Selected!');
readln;
end.
这对我来说很好,值在1到233之间,如果我输入233或更多,则不会执行writeln ..这很奇怪。我也尝试过其他值,结果或多或少相同,唯一不同的是它失败的值。
答案 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.