[再送高分] 这样的结构在 Delphi 中如何定义? (300分)

  • 主题发起人 主题发起人 x.45
  • 开始时间 开始时间
X

x.45

Unregistered / Unconfirmed
GUEST, unregistred user!
有数据的结构为:
位置 大小 说明
==========================================================================
0 2 chars 标识头,总为'gf'
2 1 Byte 数据中包含的内容,其中
bit 包含的字段
-------------------------------------------
0 Field1
1 Field2
2 Field3
3 Field4
4 Field5
5 Field6
6 Field7
7 Field8
----------------------------------
当某一位为 1 时,后面的数据区将包含该字段的值,类型为 LongWord。
3 LongWord 数据1
8 LongWord 数据2
.... LongWord 数据n
=================================================================
比如:
67 66 09 00 00 00 23 00 00 00 FF
g f ^ 35 255
|
+---00001001
就表示共有2个字段:Field1 = 35;
Field4 = 255
也就是说字段的个数是不定的。请问这样的结构如何定义?也就是下面省略号部分应该怎么写?
type
TGf = packed record
sHead: array [0..1] of char;
iStatisticStatus: Byte;
.........
end;
 
最简单就是 定义一个数组包含8个变量
如果想把问题搞的复杂一点,你定义一个链表好了 用list
 
Delphi好象没有办法用可变记录体,你这种情况可以写一个类,实现其读写方法,而使用的时候就保存最大可能的内容
PS:不知道Variant数据类型有没有用,不过直读写文件到记录是没办法的了,一定要用特殊方法
 
变体记录? C中的Union? 用Record,然后 Case....就可以了
 
定义成byte就行,读写的时候,用自定义的函数通过位操作来判断每个bit位的值
 
to ysai, 555555555 真要像你所的那样,岂不是很麻烦?难道 Delphi 就没办法了吗?
to Activer,能具体讲讲吗?谢谢!
to wfzha, 位操作到不是什么问题,不过结构中如何定义各 Field ?
 
定义一个byte就行,用的时候,通过位操作屏蔽其他的位,单独读写其中一个位
Activer说的方法大富翁上有代码,我试了一下,可以通过编译,但占的空间不是
一个字节,也不知道是不是我用错了......
没看清楚[:D]
后面的field用你的方法定义就行,读的时候判断一下byte的每个位的值,不就达到
目的了吗?
比如byte与00000001做与操作,如果值为00000001则field1有数据为00000000则field1无数据。
........
比如byte与10000000做与操作,如果值为10000000则field8有数据为00000000则field8无数据。
 
难道直接定义8个变量 来存贮8个字段不好吗?
对于变体记录:
type
TShapeList = (Rectangle, Triangle, Circle, Ellipse, Other);
TFigure = record
case FType : TShapeList of
Rectangle: (Height, Width: Real);
Triangle: (Side1, Side2, Angle: Real);
Circle: (Radius: Real);
Ellipse, Other: (Name : char);
end;

-------
var myFigure : TFigure ;
myFigure.Ftype := Rectangle;
myFigure.Height := 123;
....
myFigure.FType := Ellipse
myFigure.Name := 'A';
 
还是用类好一些,这些不适合用结构来处理。
 
我也感觉定义成Class比较好一些,关于数据不定的部分您可以把它定义类里面的一个链表,然后在这个链表里面存放相应的数据
 
凡是定义结构,连几个字节都想省下来的时候,一定是对空间要求比较高的情况。类能
节省空间吗?
 
是啊!wfzha 说的是啊!这个东东最后可能会有几十万的数据(这些数据只是最后结果的一小部分,其他部分有好几处都是这种情况)。相当庞大的数字.......
 
可不可以定义一个记录类型,每个记录的类型又是一个记录类型,
记录嵌套不就行了?
 
C里面一般是这样做的:
struct
{
char head[2];
byte flags;
long data[1];
}DATA;
然后,数据是通过动态指针进行分配,当分配的缓冲小于所需时,则返回TOO_SMALL_BUFFER之类的错误,程序则需要再次重新分配内存,然后再次调用。
很多API是这种情况,不知你的情况与此类似不?
如果是,那则可定义成:
type
PGF = ^TGF;
TGF = packed record
head: array [0..1] of Char;
flag: Byte;
data: array [0..0] of Cardinal;
end;

var
P: PGF;
当为P取得sizeof(TGF)个内存,然后进行调用时,如果出错,说明sizeof(TGF)的缓存是小于所需要调用的,一般,这种函数都会是类似这样:
function InvokeSome(P: PDataType;
var BufSize: Integer): Integer;
也就是说,如果InvokeSome调用出错,则查看它返回值,看是否缓存太小,如是,则再次:
ReallocMem(P, BufSize);
然后再调用一次InvokeSome。Goon...
使用时,则可根据P^.Data[Index]取得对应的值,说白了,就是Data首指针,偏移Index * SizeOf(Integer)取的值而已。
 
我觉得在内存中好表示,占的空间大,可以一次少读一些记录,在磁盘上存储的时候,查寻起来比较麻烦,不知道你查询的时候通过什么内容来查询?
 
呵呵!copy_paste 的方法经过实验通过!谢谢啊![:D][:D]
 
后退
顶部