| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1437 人关注过本帖
标题:[讨论]集合的内部存储方式转载与相关讨论
只看楼主 加入收藏
anthony634
Rank: 6Rank: 6
来 自:西南交大
等 级:贵宾
威 望:24
帖 子:653
专家分:10
注 册:2006-6-8
结帖率:100%
收藏
 问题点数:0 回复次数:12 
[讨论]集合的内部存储方式转载与相关讨论

转篇文章,对初学者对理解集合有一定帮助


[转]

集合类型中的存储方式...
作者:zswangII

procedure TfrmMain.FormCreate(Sender: TObject);
mysql 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*)
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存在~~


从内存存储的角度去分析这个问题,就很简单了~~
---------------------------------------------------------------

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

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

[此贴子已经被作者于2007-4-16 19:07:54编辑过]

搜索更多相关主题的帖子: mysql procedure 对话框 
2007-04-13 09:36
nongen
Rank: 5Rank: 5
来 自:网络
等 级:贵宾
威 望:17
帖 子:322
专家分:0
注 册:2006-11-25
收藏
得分:0 

procedure TfrmMain.FormCreate(Sender: TObject);
mysql 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!',请问这是为什么?
因为这个delphi系统,在你的这种情况下,会把31放在int or float里面判断。


昨天不是我的,明天不是你的,今天却是我们的。
http://www.
2007-04-13 09:41
anthony634
Rank: 6Rank: 6
来 自:西南交大
等 级:贵宾
威 望:24
帖 子:653
专家分:10
注 册:2006-6-8
收藏
得分:0 

那么 如果31改成34,是不是也会放在int or float里面判断呢?

2007-04-13 09:54
nongen
Rank: 5Rank: 5
来 自:网络
等 级:贵宾
威 望:17
帖 子:322
专家分:0
注 册:2006-11-25
收藏
得分:0 

昨天不是我的,明天不是你的,今天却是我们的。
http://www.
2007-04-13 09:55
anthony634
Rank: 6Rank: 6
来 自:西南交大
等 级:贵宾
威 望:24
帖 子:653
专家分:10
注 册:2006-6-8
收藏
得分:0 

type
myset = set of 1..30;

procedure TForm1.FormCreate(Sender: TObject);
var
testset: myset;
begin
testset := [1,6,11,5,12];
if 34 in testset then
ShowMessage('34 in testset!');//34不执行
end;

type
myset = set of 1..30;

procedure TForm1.FormCreate(Sender: TObject);
var
testset: myset;
begin
testset := [1,6,11,5,12];
if 33 in testset then
ShowMessage('33 in testset!');//执行,为什么
end;

2007-04-13 10:00
anthony634
Rank: 6Rank: 6
来 自:西南交大
等 级:贵宾
威 望:24
帖 子:653
专家分:10
注 册:2006-6-8
收藏
得分:0 

1-30因为内存对齐的原因能处理32个集合数,0-31,但是33是个很奇怪的数。

2007-04-13 10:14
anthony634
Rank: 6Rank: 6
来 自:西南交大
等 级:贵宾
威 望:24
帖 子:653
专家分:10
注 册:2006-6-8
收藏
得分:0 

更正下上面引文说的“DELPHI处理时,采用字节位进行处理
比如1,63,128等都是一个点位,
如果你用1..30那么就可以处理到63的数字 ”
点位是以字节处理,及其分配内存以4个字节为单位,所以点位是 7,31,63,95,127.


[此贴子已经被作者于2007-4-13 10:53:12编辑过]

2007-04-13 10:41
sgliuxiu
Rank: 5Rank: 5
等 级:贵宾
威 望:15
帖 子:291
专家分:0
注 册:2007-2-2
收藏
得分:0 
祝贺

小猫说:给我10元钱
2007-04-13 11:16
帅哥一条虫
Rank: 1
等 级:新手上路
威 望:1
帖 子:65
专家分:0
注 册:2006-10-15
收藏
得分:0 
看好你
2007-04-13 12:33
anthony634
Rank: 6Rank: 6
来 自:西南交大
等 级:贵宾
威 望:24
帖 子:653
专家分:10
注 册:2006-6-8
收藏
得分:0 

谢谢楼上两位,午觉又没睡,想了一个中午,终于想到为什么33可以了,因为他是1的模(0的模是32),同样,38也可以,应为他是6的模,其他的类推。

[此贴子已经被作者于2007-4-13 14:08:13编辑过]

2007-04-13 14:06
快速回复:[讨论]集合的内部存储方式转载与相关讨论
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.044849 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved