关于 pchar 和string的问题 为什么字符串'aaa' 可以直接赋值给 string , ‘aaa’也可以直接赋值给pcahr 但是 在设了一个中间变量 t:string 时候 先把'aaa'给t ,然后 t 无法赋值给 pchar? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 把pchar转换为string可用strpas(pchar),把string转换为pchar可用pchar(string) 我想问的是 ‘aaa’到底是什么类型,为什么他可以赋值给string 又能赋值给pchar? 但 string和pchar是不同类型啊 'aaa'是字符串,但它是常量字符串,在编译前期就已经可以明确它的地址了,因此,用它对PChar类型赋值,是传址(查看反汇编码可知) 用'aaa'这个常量字符串给字符串变量Str赋值,实际上也是在传址。即:Str指向'aaa'所在的内存空间;只有当以后Str的内容改变时,例如:Str := InttoStr(Self.Handle)+TimetoStr+Str;时,程序才为Str另辟内存空间,并将Str指向这个空间。----这就是Copy On Write技术。 还有 可以把一个无类型指针pointer 指向'aaa'吗? 刀刀,你说 'aaa'在编译前就有地址了,那这个地址什么什么类型呢? 是string ? 那为什么 一个 string 类型的地址可以赋值给 pchar类型?如果说 'aaa'是pchar类型的地址,那么 用'aaa'这个常量字符串给字符串变量Str赋值,实际上也是在传址。 即:Str指向'aaa'所在的内存空间; 又怎么解释? PCHAR 是一个指针而已,而STRING是一个可以自动产生内存空间的字符变量,PCHAR与STRING的转换只是地址空间的赋而已,,,, 对于CPU来说,内存中的数据没有类型。只有0和1。CPU只识得“以字节为单位取数” vart:string;p1:pointer;begin t:='aaa'; new(p1); p1:=@t; label1.Caption:=p1^; dispose(p1);end; 我想用 无类型指针 这代码怎么修改下? 对于CPU来说,内存中的数据没有类型。只有0和1。CPU只识得“以字节为单位取数”我说过了,'aaa'在编译前期(不是编译前)就有地址了,你还问“什么类型”?地址啊!编译器直接使用它的地址(也是一个常数) vart:string;p1:pchar;begin t:='aaa'; new(p1); p1:=@t; label1.Caption:=p1^; dispose(p1);end; 这个又错在哪里? 前面的您已经消化了吗?问得好快!vart:string;p1:pointer;begin t:='aaa'#0; p1:=@t[1]; label1.Caption:=StrPas(PChar(p1));end; 如果你希望自己new、dispose:vart:string;p1:pointer;begin t:='aaa'#0; new(p1); p1:=@t[1]; label1.Caption:=StrPas(PChar(p1)); p1 := nil; {注意,加这一句!} dispose(P1);end; 另外,我的代码中, 这句 label1.Caption:=StrPas(PChar(p1));里面的PChar强制转换是多余的,直接 label1.Caption:=StrPas(p1); 也可。 把前面没说完的补充一下:var Str1, Str2 : string; P : PChar;begin Str1:= 'aaa'; Str2:= 'aaa'; P := PChar(Str1); Showmessage(Format('Str1 = %p, Str2 = %p, P = %p',[Pointer(Str1),Pointer(Str2),Pointer(P)])); {看一下,地址是一样的。也就是说,Str1、Str2、P在此时都指向了'aaa'所在的内存空间(修改了引用计数)}end;Copy On Write技术很复杂。我一言两语也解释不全。况且我本人也没有全懂。需要大家一起慢慢了解了。 copy on write 技术我有关注 多谢了 刀刀 我的Q11662386 ++我吧 {把上面的例子写得更有趣一点,请看}var Str1, Str2 : string; P : PChar;begin Str1:= 'aaa'; Str2:= 'aaa'; P := PChar(Str1); {注意这里是取Str1的地址} Showmessage(Format('Str1 = %p, Str2 = %p, P = %p',[Pointer(Str1),Pointer(Str2),Pointer(P)])); {看一下,地址是一样的。也就是说,Str1、Str2、P在此时都指向了'aaa'所在的内存空间} {接下来,Str1改变,程序为Str1另辟内存空间} Str1 := InttoStr(Self.Handle) + Str1; Showmessage(Format('Str1 = %p, Str2 = %p, P = %p',[Pointer(Str1),Pointer(Str2),Pointer(P)])); {看一下地址的变化,那么,原本指向Str1[1]的P,此时该指向如何了?} Showmessage(StrPas(P)); Showmessage(Str1); {仍然指向'aaa'处,并不是新的Str1}end;{下了,休息了 ^_^ } 求助高手 DBCHART 如何动态设置它的数据源,X,Y轴? 当按窗口标题栏上的最小化按钮时,如何去执行别的事件? 如何在richedit中插入图片呢? 求救 我一打开Internet Explore,就跳出一些乱七八糟的网页,怎办呢? 如何在程序的菜单项上调windows程序 怎么让下拉式菜单里面出现图标呀? 大虾们,我觉得大家还是别走把,求你们,要给一万个机会我,我还是说i love csdn 急急急不可耐! Edit.Text输出的小数点问题 请大家帮忙看一段程序.我想在richedit中选中某行,然后将其颜色改变的.有点问题.谢谢!
即:Str指向'aaa'所在的内存空间;
只有当以后Str的内容改变时,例如:Str := InttoStr(Self.Handle)+TimetoStr+Str;
时,程序才为Str另辟内存空间,并将Str指向这个空间。
----这就是Copy On Write技术。
即:Str指向'aaa'所在的内存空间; 又怎么解释?
地址空间的赋而已,,,,
t:string;
p1:pointer;
begin
t:='aaa';
new(p1);
p1:=@t;
label1.Caption:=p1^;
dispose(p1);
end; 我想用 无类型指针 这代码怎么修改下?
对于CPU来说,内存中的数据没有类型。只有0和1。CPU只识得“以字节为单位取数”我说过了,'aaa'在编译前期(不是编译前)就有地址了,你还问“什么类型”?地址啊!编译器直接使用它的地址(也是一个常数)
t:string;
p1:pchar;
begin
t:='aaa';
new(p1);
p1:=@t;
label1.Caption:=p1^;
dispose(p1);
end;
这个又错在哪里?
前面的您已经消化了吗?
问得好快!var
t:string;
p1:pointer;
begin
t:='aaa'#0;
p1:=@t[1];
label1.Caption:=StrPas(PChar(p1));
end;
如果你希望自己new、dispose:var
t:string;
p1:pointer;
begin
t:='aaa'#0;
new(p1);
p1:=@t[1];
label1.Caption:=StrPas(PChar(p1));
p1 := nil; {注意,加这一句!}
dispose(P1);
end;
label1.Caption:=StrPas(PChar(p1));
里面的PChar强制转换是多余的,直接 label1.Caption:=StrPas(p1); 也可。
Str1, Str2 : string;
P : PChar;
begin
Str1:= 'aaa';
Str2:= 'aaa';
P := PChar(Str1);
Showmessage(Format('Str1 = %p, Str2 = %p, P = %p',[Pointer(Str1),Pointer(Str2),Pointer(P)]));
{看一下,地址是一样的。也就是说,Str1、Str2、P在此时都指向了'aaa'所在的内存空间(修改了引用计数)}
end;Copy On Write技术很复杂。我一言两语也解释不全。况且我本人也没有全懂。需要大家一起慢慢了解了。
Str1, Str2 : string;
P : PChar;
begin
Str1:= 'aaa';
Str2:= 'aaa';
P := PChar(Str1); {注意这里是取Str1的地址}
Showmessage(Format('Str1 = %p, Str2 = %p, P = %p',[Pointer(Str1),Pointer(Str2),Pointer(P)]));
{看一下,地址是一样的。也就是说,Str1、Str2、P在此时都指向了'aaa'所在的内存空间} {接下来,Str1改变,程序为Str1另辟内存空间}
Str1 := InttoStr(Self.Handle) + Str1;
Showmessage(Format('Str1 = %p, Str2 = %p, P = %p',[Pointer(Str1),Pointer(Str2),Pointer(P)]));
{看一下地址的变化,那么,原本指向Str1[1]的P,此时该指向如何了?} Showmessage(StrPas(P));
Showmessage(Str1);
{仍然指向'aaa'处,并不是新的Str1}
end;{下了,休息了 ^_^ }