Delphi類型轉換


Delphi是一種強類型轉換的語言。在VC中,賦值符用″=″,例如x=1;到了Delphi賦值符就變成了″:=″,例如x:=1。 從賦值時用符號″:=″而不用″=″,就隱約可見Delphi對類型匹配要求之嚴,即賦值符右邊的類型一定要和左邊一致。用慣了VB或VC的程序員,初用Delphi,稍不留神,就會出現類型不匹配的錯誤。對初學者而言,類型轉換也是學習Delphi的重點和難點,為此本文特對Delphi的類型轉換做一總結,以供讀者參考。
一、數的類型轉換
  把表達式的類型從一種類型轉化為另一種類型,結果值是把原始值截斷或擴展,符號位保持不變。例如:
數的類型轉換 舉例
字符轉換為整數 Integer('A')
整數轉換為字符 Char(48)
整數轉換為1個字節的邏輯型 Boolean(0)
整數轉換為2個字節的邏輯型 WordBool(0)
整數轉換為4個字節的邏輯型 LongBool(0)
整數轉換為10進制pascal型字符串 caption:=intToStr(15)
整數轉換為16進制pascal型4位字符串 caption:=intToHex(15,4)
地址轉換為長整型數 Longint(@Buffer)
 
二、數的“分開”與“合成”
取32位longint型數的高16位數為 hiword(longint-var)
低16位數為 loword(longint-var)
取16位數的 高8位數 hibyte(integer_var)
低8位數為 lobyte(integer_var)
取32位地址的段選擇符和偏移量 段選擇符(高16位地址)為 selectorof(p)
偏移量(低16位地址)為 offsetof(p)
段選擇符和偏移量合成為指針   Ptr(SEG, OFS: Word)相當於C語言的宏MK-FP(SEG,OFS)
例如在Windows中,Task DataBase結構0FAh偏移處包含'TD'標識,我們可以容易地編寫如下代碼觀察到這個位於Windows內部的未公開的秘密:
  {函數ptr(seg,ofs)的用法,相當於C語言的MK-FP(seg,ofs)}
  var p:pbyte;ch:char;
  p:=ptr(getcurrentTask,$FA);
  ch:=char(p^); {結果為ch='T'}
  p:=ptr(getcurrentTask,$FA 1);
  ch:=char(p^);   {結果為ch='D'}
 
 
三、字符串string 字符數組與指向字
  符串的指針pchar的區別與聯系
  這3者的基本概念相同,但有一些非常細微的差別,在編程時稍不注意就會出錯,需高度重視。
  1、使用指向字符串的指針,如果不是以0結尾,運行時就會出現錯誤。為了避免這種錯誤,需要在字符串結尾人工加入0 即char(0),或用strpcopy函數在字符串結尾自動加0。
  例1: 指向字符串的指針,如果不是以0結尾,運行時會出現錯誤:
  {s[0]=3 s[1]='n' s[2]='e' s[3]='w'}
  var   s:string;     p:pchar;   begin     s:='new';     label1.caption:=s; {new}     label2.caption:=intTostr(integer(s[0]));{3是字符串的長度}
   p:=@s[1];{不是以0結尾,莫用pchar型指針}    label3.caption:=strpas(p); {運行時出現錯誤}   end;
  例2:在字符串結尾人工加入0即char(0),可使用指向字符串的指針。
  {s[0]=4 s[1]='n' s[2]='e' s[3]='w' s[4]=0;}   {p-->'new'}   var         s:string; p:pchar;   begin    p:=@s[1];    s:='new' char(0); {以0結尾,可用pchar型指針}    label1.caption:=strpas(p); {new}    label2.caption:=s; {new}    label3.caption:=intTostr(integer(s[0])); {4是字符串長度}     end;
  例3: 用strpcopy函數賦值會在字符串s結尾自動加0。
  {s[0]=4 s[1]='n' s[2]='e' s[3]='w' s[4]=0;}   {p-->'new'}   var       s:string;       p:pchar;   begin    p:=@s[1];     strpcopy(p,'new');{strpcopy函數在字符串結尾自動加0}    label1.caption:=strpas(p);{new}    label2.caption:=s;{new}    label3.caption:=intTostr(integer(s[0]));{4}   end;
  2、下標為0的字符串標識符存放的是字符串長度,字符型數組基本相當於字符串,但不能存放字符串長度。字符串可以用s:='a string'的形式賦值,但是字符型數組a[ ]不可直接用a:='array'的形式賦值,用此種形式會出現類型不匹配錯誤,可選用strpcopy函數賦值。
  例4: 字符型數組s[ ]相當於字符串,但沒有存放字符串長度的位置。
  {s[1]='n' s[2]='e' s[3]='w' s[4]=0;}   {p-->'new'}   var       s:array[1..10] of char;       p:pchar;   begin    {s:='new' char(0); error}{錯誤}    p:=@s[1];    {p:=@s; is not correct}    strpcopy(p,'new');    label1.caption:=strpas(p);{new}    label2.caption:=s;{new}    {label3.caption:=intTostr(integer(s[0]));}{不會出現4, 下 超出錯誤}   end;
  例5:下標從0開始的字符數組s,s相當於@s[0]。
  { s[0]='n' s[1]='e' s[2]='w' s[3]=0;}{p-->'new'}   var       s:array[1..10] of char;       p:pchar;   begin   {s:='new' char(0); error}{錯誤}     p:=s;   {p:=@s[0] is also correct}    strpcopy(p,'new');    label1.caption:=strpas(p);{new}    label2.caption:=s;{new}    label3.caption:=s[0];{n}     end;
  3、下標從0開始和從1開始的字符數組地址的表示方法也有細微不同:
  例6:下標從1開始的數組a 與下標從0開始的數組b 的比較。
  var       a:array[1..10]of char;       b:array[0..10]of char;     {a:='1..10';}{type mismatch}     {b:='0..10';}{type mismatch}     begin    strpcopy( b, 'from 0 to 10'); {正確 因為b即是@b[0] }    strpcopy(@b[0], 'from 0 to 10'); {正確 與上個表達式 果相同}    strpcopy(@a[1], 'from 1 to 10'); {正確 }    strpcopy( a, 'from 1 to 10'); {類型匹配錯誤 因為a即是a[0]}     end;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM