//Char 类型与其编码值的转换:
var
b: Byte;
c: Char;
begin
b := Ord('A'); {返回: 65}
b := Ord(#65); {返回: 65}
b := Ord($41); {返回: 65}
b := Ord(#$41); {返回: 65}
b := Byte('A'); {返回: 65}
b := Byte(#65); {返回: 65}
b := Byte($41); {返回: 65}
b := Byte(#$41); {返回: 65}
c := Chr(65); {返回: A }
c := Chr($41); {返回: A }
c := Char(65); {返回: A }
c := Char($41); {返回: A }
end;
--------------------------------------------------------------------------------
//WideChar 类型与其编码值的转换; 汉字的 UniCode 编码范围是: $4E00..$9FA5
var
w : Word;
c : WideChar;
ws: WideString;
s : string;
begin
{准备工作}
ws := '万一';
c := ws[1];
//ShowMessage(c); {万}
{从汉字到 UniCode 编码}
w := Ord(c); {返回十进制数 : 19975}
w := Word(c); {返回十进制数 : 19975}
s := Format('%.4x',[Ord(c)]); {返回十六进制的字符串: 4E07 }
s := IntToHex(Ord(c), 4); {返回十六进制的字符串: 4E07 }
{从 UniCode 编码到汉字}
c := #19975; {万}
c := #$4E07; {万}
c := #$4e07; {万}
c := WideChar(19975); {万}
c := WideChar($4E07); {万}
end;
不同的类有不同的成员,一般子类的成员是在父类的成员的后面增加了新的成员,如果子类转为父类,那这些新增加的成员虽然还存在,但
是就不可以访问得到了。如果父类转为子类,那可能导致不可预知的错误,因为某个成员的指针指向的地址根本就不是具有实际成员。
类型的转换也有很多类的,有隐性的和显性的,一些专用的类型转换函数,会重新建立一个新类型目标对象,然后把就类型的数值移动过去
,然后销毁旧对象。一些隐性的转换,对象本身没改变,就把指针类型换一了一下。
@用于取地址!最方便的用法:
在调用Api的时候,举个例子:
我们调用Api的时候,经常要用到pchar类型,而Pchar类型的内存管理是一个很头
疼的事情。在使用时要先Getmem,最后还要freemem,如果用了@就方便了。声明一
个string类型的变量abc,然后在调用的时候使用@abc就可以了。
DateTimeToFileDate 函数 将DELPHI的日期格式转换为DOS的日期格式
DateTimeToStr 函数 将日期时间格式转换为字符串
DateTimeToString 函数 将日期时间格式转换为字符串
DateToStr 函数 将日期格式转换为字符串
FileDateToDateTime 函数 将DOS的日期格式转换为DELPHI的日期格式
FloatToDecimal 函数 将浮点数转换为十进制数
FloatToStrF 函数 将浮点数转换为字符串
FloatToStr 函数 将浮点数转换为字符串
FloatToText 函数 将给定的浮点数转换为十进制数
FloatToTextFmt 函数 将给定的浮点数转换为十进制数
IntToHex 将整型数转换为十六进制数
IntToStr 将整型数转换为字符串
StringToWideChar 函数 将ANSI字符串转换为UNICODE字符串
StrToDate 函数 将字符串转换为日期格式
StrToDateTime 函数 将字符串转换为日期/时间格式
StrToFloat 函数 将给定的字符串转换为浮点数
StrToInt 函数 将字符串转换为整型
StrToIntDef 函数 将字符串转换为整型或默认值
StrToTime 函数 将字符串转换为时间格式
TextToFloat 函数 将字符串(以NULL结束的格式)转换为浮点数
TimeToStr 函数 将时间格式转换为字符串
VarToDateTime 函数 将给定的变体转换为日期时间
WideCharLenToString 函数 将ANSI字符串转换为UNICODE字符串
WideCharToString 函数 将UNICODE字符串转换为ANSI字符串
WideCharToStrVar 函数 将UNICODE字符串转换为ANSI字符串变量
procedure GetMem(var P: Pointer; Size: Integer);
//分配动态内存
function StrPas(const Str: PChar): string;
//将PChar转换为String
在我们编写程序当中,根据不同情况,会使用到多种数据类型。当要对不同的类型进行操作时,必须要将不同的类型转换成同样的类型。因此熟练地掌握数据类型的转换是非常重要的。
1.FloatToStr
功能说明:该函数用于将“浮点型”转换成“字符型”。
Edit1.Text := FloatToStr(1.981);
2.IntToStr
功能说明:该函数用于将“整数型”转换成“字符型”。
S := IntToStr(10);(注:S为String类型变量。)
3.IntToHex
功能说明:该函数用于将“十进制”转换成“十进制”。该函数有二个参数。第一个参数为要转换的十进制数据,第二个参数是指定使用多少位来显示十六进制数据。
Edit1.Text := IntToHex(''100'', 2);
执行结果,Edit1.Text等于64。
注意:Delphi没有提供专门的“十六进制”转换为“十进制”的函数。使用StrToInt函数可以实现这个功能。具体代码是:I := StrToInt(''S\'' + ''64''); 这时I等于100。加上一个''S\''即可将“十六进制”转换为“十进制”。
4.StrToInt
功能说明:该函数用于将“字符型”转换成“整数型”。
I := StrToInt(''100'');
注意:不能转换如 StrToInt(''ab'')或StrToInt(''好'')这样的类型,因为他们并不存在数字型。
4.2 StrToIntdef('字符',数字)
功能说明:返回字符串S转换成整数
说明 字符串非整数表达时则返回默认值Default
SpinEdit1.Value := StrToIntDef(Edit1.Text, 0);
注意:当Edit1.Text转换成非整数表达时,则返回默认值0。
5.StrToFloat
功能说明:该函数用于将“字符型”转换成“浮点型”。
N := StrToFloat(Edit1.Text);
注意:Edit1.Text中的内容为1.981(凡在Edit控件中显示的文本均为字符串)。N为Double类型,用于保存转换后的浮点型数据。
DateTimeToFileDate 函数 将DELPHI的日期格式转换为DOS的日期格式
DateTimeToStr 函数 将日期时间格式转换为字符串
DateTimeToString 函数 将日期时间格式转换为字符串
DateToStr 函数 将日期格式转换为字符串
FileDateToDateTime 函数 将DOS的日期格式转换为DELPHI的日期格式
FloatToDecimal 函数 将浮点数转换为十进制数
FlatToStrF 函数 将浮点数转换为字符串
FloatToStr 函数 将浮点数转换为字符串
FloatToText 函数 将给定的浮点数转换为十进制数
FloatToTextFmt 函数 将给定的浮点数转换为十进制数
IntToHex 将整型数转换为十六进制数
IntToStr 将整型数转换为字符串
StringToWideChar 函数 将ANSI字符串转换为UNICODE字符串
StrToDate 函数 将字符串转换为日期格式
StrToDateTime 函数 将字符串转换为日期/时间格式
StrToFloat 函数 将给定的字符串转换为浮点数
StrToInt 函数 将字符串转换为整型
StrToIntDef 函数 将字符串转换为整型或默认值
StrToTime 函数 将字符串转换为时间格式
TextToFloat 函数 将字符串(以NULL结束的格式)转换为浮点数
TimeToStr 函数 将时间格式转换为字符串
VarToDateTime 函数 将给定的变体转换为日期时间
WideCharLenToString 函数 将ANSI字符串转换为UNICODE字符串
WideCharToString 函数 将UNICODE字符串转换为ANSI字符串
WideCharToStrVar 函数 将UNICODE字符串转换为ANSI字符串
一、数的类型转换
把表达式的类型从一种类型转化为另一种类型,结果值是把原始值截断或扩展,符号位保持不变。例如:
数的类型转换 举例
字符转换为整数 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;
0
0
0
】Delphi中关键字,优先法则,类型转换等相关
Trunc 转换一个实型值为小数截断后的整型值
Int 返回浮点数的整数部分
IntToStr 将数值转换为字符串
IntToHex 将数值转换为十六进制数字符串
StrToInt 将字符串转换为一个整型数,如字符串不是一个合法的整型将引发异常
StrToIntDef 将字符串转换为一个整数,如字符串不合法返回一个缺省值
Val 将字符串转换为一个数字(传统Turbo Pascal例程用于向后兼容)
Str 将数字转换为格式化字符串(传统Turbo Pascal例程用于向后兼容)
StrPas 将零终止字符串转换为Pascal类型字符串,在32位Delphi中这种类型转换是自动进行的
StrPCopy 拷贝一个Pascal类型字符串到一个零终止字符串, 在32位Delphi中这种类型转换是自动进行的
StrPLCopy 拷贝Pascal类型字符串的一部分到一个零终止字符串
FloatToDecimal 将一个浮点数转换为包含指数、数字及符号的十进制浮点记录类型
FloatToStr 将浮点值转换为缺省格式的字符串
FloatToStrF 将浮点值转换为特定格式的字符串
FloatToText 使用特定格式,将一个浮点值拷贝到一个字符串缓冲区
FloatToTextFmt 同上面例程,使用特定格式,将一个浮点值拷贝到一个字符串缓冲区
StrToFloat 将一个Pascal字符串转换为浮点数
TextToFloat 将一个零终止字符串转换为浮点数
Dec 将例程中的参数值递减1或一个特定的值,其中特定值可在第二个可选参数中定义
Inc 将例程中的参数值增加1或一个特定的值
Odd 如果参数为奇数返回真
Pred 根据参数在其数据类型定义中的序列,返回参数值的前驱值
Succ 返回参数值的后继值
Ord 返回参数值在其数据类型值集合中的序号
Low 返回参数对应的有序数据类型的最小取值
High 返回参数对应的有序数据类型的最大取值
实数:
Single
Double
Extended
Real {$REALCOMPATIBILITY ON}据说不标准,要兼容旧的格式使用这个宏
Comp
Currency
TDateTime = type Double
为了后续使用或直接用于变量,需要给自定义类型命名。如果自定义一个命名的类型,你必须将代码放在特定的type区,如下所示:
最多的如定义类等。
type
Uppercase = 'A'..'Z';
Temperatures = array [1..24] of Integer;
Date = record
Month: Byte;
Day: Byte;
Year: Integer;
end;
Colors = (Red, Yellow, Green, Cyan, Blue, Violet);
Letters = set of Char;
end;
子界类型
a...b
a~b为有序类型
枚举类型
type
Colors = (Red, Yellow, Green);//园括弧括起来的,在属性列表中最多出现。
end;
只能有一个值
CPP = enum
集合类型
type Letters = set of Char;
var Letters1,Letters2etters;
begin
Letters1 := ['A'.'B'.'C'];
Letters2 := ['K'];
end;
是什么什么的集合,可以有多个属性。
CPP = 多字段与或
Font.style := [fsBold, fsItalic]; // two styles
Font.style :=Oldstyle + [fsBold, fsItalic];
数组类型
type
MonthTemps = array [1..24, 1..31] of Integer;
YearTemps = array [Jan..Dec] of Integer;
记录类型
type
Date = record
Year: Integer;
Month: Byte;
Day: Byte;
end;
类似 structure
指针
type
PointerToInt = ^Integer;
var
P:^Integerl
X:Integer;
begin
P := @X; p = &x;
X :=10; x = 10;
P^ :=20; *p = 20;
end;
除了表示已分配内存的地址外,指针还能通过New 例程在堆中动态分配内存,不过当你不需要这个指针时,你也必须调用Dispose 例程释放你动态分配的内存。
P:=nil;
Pointer 类型,如void *;
实际上,Delphi 中必须使用指针的情况很少,这是Delphi开发环境一个诱人的优点。
文件类型
type
IntFile = file of Integer;
能打开一个与这个结构相应的物理文件、向文件中写入整数、或者从文件中读取当前的值
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
怎样才能访问pointer指针的所有数据?(最好有多种方法一起说明)
例:
var
p:pointer
begin
p:=一个指针变量
p:=p+1;//为什么不能这样使用?怎样才能指向下一个地址?
end;
var
p: pointer;
s: string;
begin
s:= 'abc';
p:= PChar(s); //给指针赋值
p:= Pointer(Integer(p)+1); //把指针后移一位
Caption:= string(Char(p^)); //读取后移后的指针内容
end;
我有这样一段代码
var
Pos: Byte;
PP: PByte;
Pos := 1
PP := PP + Pos;
PP^ := 12;
在这三句话中Delphi老是说第二句有错误,我知道如果写成这样是没有问题的PP【Pos】 := 12;
但是有时候就是感觉和C的不一样,不习惯(一直是用C做底层的东东,改了太难受了,呵呵)
Delphi 里面的Integer 和 Pointer, 0 和 nil前两天,一个同事问我关于Delphi里面Pointer的问题,便和他一起推敲, 结果发现一个有趣的结论:Delphi里面, nil = 0; 想想,这也是很好理解的, 在32位Windows操作系统里面, 一个整数是32位, 一个指针也是32位的无符号整数。 但是,具体编程上的操作,却比较有趣, 各位老大请看:
vara : Pointer;
begin
// a := nil;
if Assigned(a)
thenbegin ShowMessage('我有种')
endelse begin ShowMessage('我没种')
endend; 结果是:'我有种', 说明Pointer和Integer一样,声明后,必须初始化。再看下面:
vara : Pointer;
begina := 0;
if Assigned(a)
thenbeginShowMessage('我有种')
endelse begin ShowMessage('我没种')
endend; 结果是:'我没种', 说明对于Pointer,nil其实就是等于这个Pointer里面的内存地址是$00000000。
指针 Pointer @
var p1,p2,p3:pointer
S:String;
I:Integer;
begin
p1:= Pointer(S);
p2:= @S;
P3:= pchar(s);
// p1 和 p2 p3 有什么区别吗?
// Pointer(S)^ 字符串和Buffer
end;
Pointer 是Borland VCL 的一个结构类型.
因此还有 PPointer 这样一个东东呢!.指针的指针,如同管理类的类.
@是取地址的操作.什么都可以取地址.但取出来的不一定可以进行内容的访问.
这就是一个数了,脱离了实际的现场就没有意义了。(一个变量不可能下次还使用同一个物理内存吧 呵呵)
pchar 指的是字符串数组的首地址. 后面连续的字符串直到 "\0" 结束.
雖說有些需用到的功能Delphi或第三方大都已提供元件或原始碼,
但如果欲從C++自己轉些碼來用真是麻煩,
看看下面
function GetHostAddress(const hostname : string) : u_long;
var
pHostAddr : PHostEnt;
type
T = ^u_long;
begin
pHostAddr := gethostbyname(PCHAR(hostname));
if (pHostAddr = nil) then
begin
result := 0;
end
else
begin
result := T(pHostAddr^.h_addr^)^;
end;
end;
想來必定是從C++直接按範例寫的, 但能看出在做什麼呢?
指標在Object Pascal Language Guide有提及, 還有Delphi學習筆記
也有一小段落也提起。
但以我的觀念, 大致上只會用到如此而已
type
TStruct=record
no:integer;
name:string;
end;
PStruct=^TStruct;
var
i:integer;
pi:PInteger;
group:array[0..10] of TStruct;
PMember:PStruct;
begin
pi:=@i;
pi^:=10;
ShowMessage(IntToStr(i));
PMember:=@group[0];
PMember.no:=1;
PMember.name:='曾水舜';
Inc(PMember);
PMember.no:=2;
PMember.name:='sunshine';
ShowMessage(group[0].name);
Dec(PMember);
PMember^.name:='愛玩';
ShowMessage(group[0].name);
end;
一起研究吧....
>我想大部分人用 delphi 來開發資料庫
>用到Pointer實在不多,很多事Delphi 已經幫你做的好好地(如動態陣列)
>不像 C++ 還要自己控制,So....至少到目前為止我只用過他在動態 Record 上
>除非要做很低階控制,不過這可能不會用 delphi 來作吧
>anyway 手冊上那一本介紹pascal 講的蠻詳細地
>>經常看到一些 Sample code 都會使用到 Pointer. 但不論中文或英文書都
>>什少提及 Pointer. 就算有頁數亦很少. 幾巳遺忘 Delphi 有 Pointer.
在Delphi中使用指针参数
在c语言中用function (int ^par)很方便,查过好多资料没找到delphi的用法,
今晚没事突然想起用delphi万能指针pointer(无类型指针)应该可以代替。测试一下通过。
procedure xx(a:pchar); 【扩展信息:用 Javascript 实现的“Dua】
var
tm:^tadodataset;
begin
tm:=pointer(a);
...
end;
procedure bb;
var
tm:tadodataset;
begin
tm...
xx(@tm);
end;