首先:pchar是指针类型。这个于c语言的字符串比较类似,也是以空字符为结束符。
而string只有pascal才有,标准的string只能有256个字节,下标从1开始,实际上
string也是从0开始的,但是string[0]这个元素存储的是字符串的长度,所以这个导致了标准的string只能由256个字节长。而后来扩展的string也可以存储超过256字节的东西。
两者之间的转换:
我只写比较标准,绝对无错的用法:
string-->pchar
var P:PChar;
var Str:String;
begin
Str:='Hello';
GetMem(P,Length(Str)+1);
StrPCopy(P,Str);
ShowMessage(StrPas(P));
end;
pchar---->string只要调用strpas
而string只有pascal才有,标准的string只能有256个字节,下标从1开始,实际上
string也是从0开始的,但是string[0]这个元素存储的是字符串的长度,所以这个导致了标准的string只能由256个字节长。而后来扩展的string也可以存储超过256字节的东西。
两者之间的转换:
我只写比较标准,绝对无错的用法:
string-->pchar
var P:PChar;
var Str:String;
begin
Str:='Hello';
GetMem(P,Length(Str)+1);
StrPCopy(P,Str);
ShowMessage(StrPas(P));
end;
pchar---->string只要调用strpas
这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;
var
p:PChar;
s:String;
...
p:=PChar(s);
s:=String(p);
-----------------
不是我神经出了问题,而是你还太嫩.我天天玩Delphi已经4年.年轻人,学知识要谦虚,不要出口不逊.行不行你测试一下不就行了?
说多了反而会让人头昏,
概念上 pchar是指针或者数组,string是变量(在某些语言里是类,最好当作类来看待)
使用上pchar 一般用法要先申请空间,然后使用strcopy,不要使用“=”,(我刚开始使用的时候就犯过这个错,害我查错查了好几天)最后还要释放空间,
string我就不用说了,好方便,
为什么要pchar类型呢,因为是为了 api函数接口,全部是pchar 类型的,没有string类型(如果把string当作类而不当作数据类型的话就容易理解着一点了),还有dll的参数,也不可以使用string,要用pchar,否则程序经常会出一些莫名其妙的问题,
SetLength可以用于String和动态数组,而不能用于类.当你设置了动态数组的长度后,你是否需要SetLength(MyArray,0)来释放空间?不需要,因为对于动态数组而言,当他没有任何引用时,Delphi会自动删除它.String同样,它就是动态数组.至于你使用"="引起了错误,是因为你概念不清而引起的,并不是说,必须要用strcopy而不能用pchar.还是那句话,看到内存空间去.