[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內部的未公開的秘密:
var p:pbyte;ch:char;
p:=ptr(getcurrenttask,$fa);
ch:=char(p^);
p:=ptr(getcurrenttask,$fa+1);
ch:=char(p^);
三、字串string 字元陣列與指向字
符串的指標pchar的區別與聯絡
這3者的基本概念相同,但有一些非常細微的差別,在程式設計時稍不注意就會出錯,需高度重視。
1、使用指向字串的指標,如果不是以0結尾,執行時就會出現錯誤。為了避免這種錯誤,需要在字串結尾人工加入0 即char(0),或用strpcopy函式在字串結尾自動加0。
例1: 指向字串的指標,如果不是以0結尾,執行時會出現錯誤:
vars:string;
p:pchar;
begin
s:='new';
label1.caption:=s;
label2.caption:=inttostr(integer(s[0]));
p:=@s[1];
label3.caption:=strpas(p);
end;
例2:在字串結尾人工加入0即char(0),可使用指向字串的指標。
var
s:string;
p:pchar;
begin
p:=@s[1];
s:='new'+char(0);
label1.caption:=strpas(p);
label2.caption:=s;
label3.caption:=inttostr(integer(s[0]));
end;
例3: 用strpcopy函式賦值會在字串s結尾自動加0。
var
s:string;
p:pchar;
begin
p:=@s[1];
strpcopy(p,'new');
label1.caption:=strpas(p);
label2.caption:=s;
label3.caption:=inttostr(integer(s[0]));
end;
2、下標為0的字串識別符號存放的是字串長度,字元型陣列基本相當於字串,但不能存放字串長度。字串可以用s:='a string'的形式賦值,但是字元型陣列a[ ]不可直接用a:='array'的形式賦值,用此種形式會出現型別不匹配錯誤,可選用strpcopy函式賦值。
例4: 字元型陣列s[ ]相當於字串,但沒有存放字串長度的位置。
var
s:array[1..10] of char;
p:pchar;
begin
p:=@s[1];
strpcopy(p,'new');
label1.caption:=strpas(p);
abel2.caption:=s;
end;
例5:下標從0開始的字元陣列s,s相當於@s[0]。
var
s:array[1..10] of char;
p:pchar;
begin
p:=s;
strpcopy(p,'new');
label1.caption:=strpas(p);
label2.caption:=s;
label3.caption:=s[0];
end;
3、下標從0開始和從1開始的字元陣列位址的表示方法也有細微不同:
例6:下標從1開始的陣列a 與下標從0開始的陣列b 的比較。
var
a:array[1..10]of char;
b:array[0..10]of char;
begin
strpcopy( b, 'from 0 to 10');
strpcopy(@b[0], 'from 0 to 10');
strpcopy(@a[1], 'from 1 to 10');
strpcopy( a, 'from 1 to 10');
end;
強制型別轉換
關於強制型別轉換的問題,很多書都討論過,寫的最詳細的是c 之父的 c 的設計和演化 最好的解決方法就是不要使用c風格的強制型別轉換,而是使用標準c 的型別轉換符 static cast,dynamic cast。標準c 中有四個型別轉換符 static cast dynamic cast reint...
強制型別轉換
顯式轉換也稱為強制型別轉換 cast 包括以下列名字命名的強制型別轉換操作符 static cast dynamic cast const cast 和 reinterpret cast。命名的強制型別轉換符號的一般形式如下 cast name expression 其中 cast name 為 s...
強制型別轉換
c 風格的型別轉換提供了4種型別轉換操作符來應對不同場合的應用。const cast,字面上理解就是去const屬性。static cast,命名上理解是靜態型別轉換。如int轉換成char。dynamic cast,命名上理解是動態型別轉換。如子類和父類之間的多型型別轉換。reinterprete...