CnPack Forum


 
Subject: MicroTip#3 pascal Union 的一个应用
skyjacker
版主
Rank: 7Rank: 7Rank: 7
茶农


UID 2239
Digest Posts 9
Credits 617
Posts 269
点点分 617
Reading Access 100
Registered 2006-6-8
Status Offline
Post at 2007-3-19 17:39  Profile | Blog | P.M.  | QQ
MicroTip#3 pascal Union 的一个应用

MicroTip#3 pascal Union 的一个应用
// Test in Delphi6 up2
// Wrtten by SkyJacker 2007.03.19
// QQ Discuss Group: 130970

1、通过类型转换,实现获取某个字的高低字节。

之前使用字的移位或 Hi,Lo 来得到,Union 也可以阿。

procedure TFrmTest.btnTest(Sender: TObject);
type
  TWordRec = packed record
    case Integer of
      0: (Lo, Hi: Byte); // 先低字节,后高字节(内存实际存放位置)
      1: (Bytes: array [0..1] of Byte); // 先低字节,后高字节(内存实际存放位置)
  end;
var
  H, L: Byte;
  W: Word;
  W2:TWordRec;
begin
  W := $01AA;
  W2 := TWordRec(W);
  H := W2.Hi;
  L := W2.Lo;
  ShowMessage('1. ' + IntToHex(W, 4) + '-' + IntToHex(H, 2) + '-' + IntToHex(L, 2));
end;

Union 还有哪些其他的应用呢?

[ 本帖最后由 skyjacker 于 2007-3-19 17:43 编辑 ]




一壶清茶煮青春.
Top
kendling (小冬)
高级版主
Rank: 8Rank: 8
MyvNet


Medal No.1  
UID 703
Digest Posts 5
Credits 978
Posts 580
点点分 978
Reading Access 101
Registered 2005-2-18
Location 广东
Status Offline
Post at 2007-3-20 10:06  Profile | Site | Blog | P.M.  | QQ | Yahoo!
我一直都不懂record里的case,其实是什么意思?实际应该怎么写?




小冬
http://MyvNet.com
Top
Passion (LiuXiao)
管理员
Rank: 9Rank: 9Rank: 9


UID 359
Digest Posts 19
Credits 6760
Posts 3556
点点分 6760
Reading Access 102
Registered 2004-3-28
Status Offline
Post at 2007-3-20 10:31  Profile | Blog | P.M. 
case似乎没起实际作用,只是表示随着case的值不一样而定义的东西也不同。
Top
skyjacker
版主
Rank: 7Rank: 7Rank: 7
茶农


UID 2239
Digest Posts 9
Credits 617
Posts 269
点点分 617
Reading Access 100
Registered 2006-6-8
Status Offline
Post at 2007-3-20 12:15  Profile | Blog | P.M.  | QQ
是啊, case 在编程中没有任何作用.
应该是编译器识别 pascal union 的标志.   

unnion 在 Delphi   中的使用,主要用于兼容不同的类型:
(因为可以使用类型转换TWordRec(), 所以节省空间的作用, 看不出来啊)

var
  Bs: array[0..1] of byte;
begin
  Bs[0] := $AA;
  Bs[1] := $01;
  //W := $01AA;
  W2 := TWordRec(Bs);
  H := W2.Hi;
  L := W2.Lo;
  ShowMessage('1. ' + IntToHex(Word(Bs), 4) + '-' + IntToHex(H, 2) + '-' + IntToHex(L, 2));
end;

=================================================
Delphi SysUtils.pas  中的 Union:
{ Type conversion records }

  WordRec = packed record
    case Integer of
      0: (Lo, Hi: Byte);
      1: (Bytes: array [0..1] of Byte);
  end;

  LongRec = packed record
    case Integer of
      0: (Lo, Hi: Word);
      1: (Words: array [0..1] of Word);
      2: (Bytes: array [0..3] of Byte);
  end;

  Int64Rec = packed record
    case Integer of
      0: (Lo, Hi: Cardinal);
      1: (Cardinals: array [0..1] of Cardinal);
      2: (Words: array [0..3] of Word);
      3: (Bytes: array [0..7] of Byte);
  end;

function TThreadLocalCounter2.HashIndex: Byte;
var
  H: Word;
begin
  H := Word(GetCurrentThreadID);
  Result := (WordRec(H).Lo xor WordRec(H).Hi) and 15;
end;
..............




一壶清茶煮青春.
Top
shenloqi
灌水处处长
Rank: 4



UID 34
Digest Posts 1
Credits 287
Posts 179
点点分 287
Reading Access 10
Registered 2003-3-15
Status Offline
Post at 2007-3-20 16:01  Profile | P.M. 
Union中的case的确没有什么用途,理论上Pascal的编译器应该会根据这个类型进行一些判断的,也就是说如果case的值和能访问的内容是对应的,不过实际上基本上所有的编译器都没有这么做,我想应该是考虑到与C的兼容性吧,毕竟如果加上了这个校验就没有了能和C里面等价的东西了(除了指针操作或者强制转换)。

Union的用途主要在节省内存和与其他语言的交互,有时还有一些特殊的用途,如:Delphi 2007似乎就使用了Union做了一些Hack的事情来保存Vista中的GlassFrame的一些属性的。
Top
kendling (小冬)
高级版主
Rank: 8Rank: 8
MyvNet


Medal No.1  
UID 703
Digest Posts 5
Credits 978
Posts 580
点点分 978
Reading Access 101
Registered 2005-2-18
Location 广东
Status Offline
Post at 2007-3-20 23:56  Profile | Site | Blog | P.M.  | QQ | Yahoo!
喔喔。。。




小冬
http://MyvNet.com
Top
 




All times are GMT++8, the time now is 2024-5-1 05:16

    本论坛支付平台由支付宝提供
携手打造安全诚信的交易社区 Powered by Discuz! 5.0.0  © 2001-2006 Comsenz Inc.
Processed in 0.007647 second(s), 8 queries , Gzip enabled

Clear Cookies - Contact Us - CnPack Website - Archiver - WAP