为什么字符串'aaa' 可以直接赋值给 string   , ‘aaa’也可以直接赋值给pcahr 但是 在设了一个中间变量 t:string 时候 先把'aaa'给t ,然后 t 无法赋值给 pchar?

解决方案 »

  1.   

    把pchar转换为string可用strpas(pchar),把string转换为pchar可用pchar(string) 
      

  2.   

    我想问的是 ‘aaa’到底是什么类型,为什么他可以赋值给string 又能赋值给pchar?  但 string和pchar是不同类型啊
      

  3.   

    'aaa'是字符串,但它是常量字符串,在编译前期就已经可以明确它的地址了,因此,用它对PChar类型赋值,是传址(查看反汇编码可知)
      

  4.   

    用'aaa'这个常量字符串给字符串变量Str赋值,实际上也是在传址。
    即:Str指向'aaa'所在的内存空间;
    只有当以后Str的内容改变时,例如:Str := InttoStr(Self.Handle)+TimetoStr+Str;
    时,程序才为Str另辟内存空间,并将Str指向这个空间。
    ----这就是Copy On Write技术。
      

  5.   

    还有 可以把一个无类型指针pointer 指向'aaa'吗?
      

  6.   

    刀刀,你说 'aaa'在编译前就有地址了,那这个地址什么什么类型呢? 是string ?  那为什么 一个 string 类型的地址可以赋值给 pchar类型?如果说 'aaa'是pchar类型的地址,那么  用'aaa'这个常量字符串给字符串变量Str赋值,实际上也是在传址。 
    即:Str指向'aaa'所在的内存空间; 又怎么解释?
      

  7.   

     PCHAR 是一个指针而已,而STRING是一个可以自动产生内存空间的字符变量,PCHAR与STRING的转换只是
    地址空间的赋而已,,,,
      

  8.   

    对于CPU来说,内存中的数据没有类型。只有0和1。CPU只识得“以字节为单位取数”
      

  9.   

    var
    t:string;
    p1:pointer;
    begin
      t:='aaa';
      new(p1);
      p1:=@t;
      label1.Caption:=p1^;
      dispose(p1);
    end;    我想用 无类型指针 这代码怎么修改下?
      

  10.   


    对于CPU来说,内存中的数据没有类型。只有0和1。CPU只识得“以字节为单位取数”我说过了,'aaa'在编译前期(不是编译前)就有地址了,你还问“什么类型”?地址啊!编译器直接使用它的地址(也是一个常数)
      

  11.   

    var
    t:string;
    p1:pchar;
    begin
      t:='aaa';
      new(p1);
      p1:=@t;
      label1.Caption:=p1^;
      dispose(p1);
    end;
     这个又错在哪里?
      

  12.   


    前面的您已经消化了吗?
    问得好快!var
    t:string;
    p1:pointer;
    begin
      t:='aaa'#0;
      p1:=@t[1];
      label1.Caption:=StrPas(PChar(p1));
    end;
      

  13.   


    如果你希望自己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;
      

  14.   

    另外,我的代码中, 这句
      label1.Caption:=StrPas(PChar(p1));
    里面的PChar强制转换是多余的,直接 label1.Caption:=StrPas(p1); 也可。
      

  15.   

    把前面没说完的补充一下: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技术很复杂。我一言两语也解释不全。况且我本人也没有全懂。需要大家一起慢慢了解了。
      

  16.   

    copy on write 技术我有关注  多谢了 刀刀  我的Q11662386  ++我吧
      

  17.   

    {把上面的例子写得更有趣一点,请看}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;{下了,休息了 ^_^ }