procedure TfrmMain.FormCreate(Sender: TObject);
type
  myset = set of 1..30;
var
  testset: myset;
begin
  testset := [1,6,11,5,12,31];
  if 31 in testset then
    ShowMessage('31 in testset!');
end;照书上的说31这个元素已经超出了myset集合允许的范围,但测试的结果是程序还是弹出了对话框显示'31 in testset!',请问这是为什么?

解决方案 »

  1.   

    31不是在testset中吗???当然会出现这个提示了。
      

  2.   

    问题是31超出了1..30的范围啊,31怎么会被放到testset中来的呢?
      

  3.   

    既然已经编译过了,肯定运行正常
    像myset = set of 1..30;
    而31又可以被赋值,kh和编译器的选项有关
      

  4.   

    可是若把31改成100
    procedure TfrmMain.FormCreate(Sender: TObject);
    type
      myset = set of 1..30;
    var
      testset: myset;
    begin
      testset := [1,6,11,5,12,100];
      if 100 in testset then
        ShowMessage('100 in testset!');
    end;按楼上的说法应该会出现'100 in testset!',但测试结果不会出现。
      

  5.   

    procedure TfrmMain.FormCreate(Sender: TObject);
    type
      myset = set of 1..30;
    var
      testset: myset;
    begin
      testset := [1,6,11,5,12,31];
      if 31 in testset then
        ShowMessage('31 in testset!');
    end;照书上的说31这个元素已经超出了myset集合允许的范围,但测试的结果是程序还是弹出了对话框显示'31 in testset!',请问这是为什么?
    /////////////////////////////////////
    因为:
    testset := [1,6,11,5,12,31];  // 所以 31 是 testset的一个元素;
      

  6.   

    type
      myset = set of 1..30;
    改成
    type
      myset = set of 1..17;
    结果相同,怪事!
      

  7.   

    是有点邪门,32就不行,就31列外。
    而且
    myset=set of 1..(小于31的任何数都行)
      

  8.   

    这是由于集合的存储方式产生的现象~~要了解这个问题先要分析集合类型在内存中是如何存储的~~来一步一步测试看~~(*例子1*)
    type
      TSetTest = set of 0..7;
    var
      S: TSetTest;
    begin
      S := [0, 1, 3];
      Memo1.Lines.Values['SizeOf(S)'] := IntToStr(SizeOf(S));
      Memo1.Lines.Values['S'] := IntToHex(Byte(S), 0);
    end;-------Memo1.Text-------
    SizeOf(S)=1 //这说明0..7的集合占用了一个字节~~
    S=B //二进制(0000 1011) 说明一个字位表示一个元素是否存在~~
    -------------7654 3210 //0, 1, 3存在~~(*例子2*)
    type
      TSetTest = set of 0..8;
    var
      S: TSetTest;
    begin
      S := [0, 1, 3];
      Memo1.Lines.Values['SizeOf(S)'] := IntToStr(SizeOf(S));
      Memo1.Lines.Values['S'] := IntToHex(Byte(S), 0);
    end;-------Memo1.Text-------
    SizeOf(S)=2 //目前有9个元素,按照一个字位存放一个元素,可以推论:一个集合的大小等于该集合元素总数 div 8+ 1~~
    S=B //二进制(0000 0000|0000 1011) 这里看以看出还有7个字位是空余的~~
    -------------5432 1098 7654 3210 //0, 1, 3存在~~
    (*例子2*)
    procedure TForm1.Button2Click(Sender: TObject);
    type
      TSetTest = set of 7..8;
    var
      S: TSetTest;
    begin
      S := [0, 1, 3];
      Memo1.Lines.Values['SizeOf(S)'] := IntToStr(SizeOf(S));
      Memo1.Lines.Values['S'] := IntToHex(Word(S), 0);
    end;-------Memo1.Text-------
    SizeOf(S)=2 //按照上面的推论,7..8只有两个元素,占用1个字节(2 div 8 + 1=1),可实际是2个字节,因为集合存储起始元素的序号只能是0、8、16……等2的次方数,估计是为了提高运算效率~~
    S=B //二进制(0000 0000|0000 1011)
    -------------5432 1098 7654 3210 //0, 1, 3存在~~
    从内存存储的角度去分析这个问题,就很简单了~~
      

  9.   

    这是DELPHI对集合的处理方式问题
      

  10.   

    DELPHI处理时,采用字节位进行处理
    比如1,63,128等都是一个点位,
    如果你用1..30那么就可以处理到63的数字
      

  11.   

    你已经做了赋值语句:
    testset := [1,6,11,5,12,31];所以
    if 31 in testset then
      ShowMessage('31 in testset!');
    这个肯定成立了。因为31就在[1,6,11,5,12,31]中的一个成员。
    如果你只有:
    type
      myset = set of 1..30;
    而没有赋值语句:
    testset := [1,6,11,5,12,31];
    结果就不一样了.
    因为是testset是以最后的赋值为基准的