@string  和pchar(string) 有什么区别?  

解决方案 »

  1.   

    var
      S: string;
      P : PChar;
    begin
      S := FormatDatetime('YYYYMMMMDDhhnnsszzz', Now);
      P := PChar(S);
      Showmessage(Format('%p,%p,%p', [@S, @S[1], Pointer(P)]));
      {看一下区别。@S是取S变量的地址;而P := PChar(S)等效于P := @S[1]}
    {请注意!为什么S赋值没有用字符串常量?因为字符串常量的引用计数总是-1,P:=PChar(S)时会发生复制}
    end;
      

  2.   

    再给你一个演示,请仔细分析代码,看一下显示的五个地址var
      S: string;
      P : PChar;
    begin
      S := FormatDatetime('YYYYMMMMDDhhnnsszzz', Now);
      P := PChar(S);
      Showmessage(Format('%p,%p,%p,%p,%p', [Pointer(S), @S, @S[1], Pointer(P), Pointer(string((@S)^))]));
    end;
      

  3.   

    刀刀 ,用昨天的例子 你说  t:string='aaa'是字符串,但它是常量字符串,在编译前期就已经可以明确它的地址了 那这个地址是不是@t? 然后你说'aaa'赋值给一个 p:pchar是不是把'aaa' 的地址穿给p? 那两个地址不是一样了吗?
      

  4.   


    昨天说的是'aaa',而不是全局变量t:string='aaa'
    当然,没有什么本质的区别
    编译前期就已经可以明确'aaa'的地址,是指第一个'a'所在的那个字节的地址(即@t[1]),而不是@t
    @t是变量t所在的那四个字节的地址(这四个字节存放着@t[1])。从@t[1]处开始,是t的整个字符序列,直到#0
    'aaa' 与 全局变量t:string='aaa' 的区别在于,前者没有变量名字。在这里,还需要说一下进程的内存格局:
    按照C++书上的理论,一个程序的内存格局通常分为四个区:
    1、全局数据区
    2、代码区
    3、栈
    4、堆
    不知Delphi编译器是否也是这样规划,但我想既然是Windows程序,应该也是这样的了。因此,对于全局变量S来说:
    S(四个字节),在全局数据区。因此@S是指向全局数据区。其他全局变量如窗体、StringList,都在这里。(注意!只是变量在这里)
    S[1],在堆内存中。当声明全局变量时,并不进行堆内存分配,只有为它赋值时,才进行分配。同理,窗体变量(如Form1)、StringList、BMP等等,其变量指向的空间(即实例所在空间),也在堆里。当Create时,它们的堆内存空间才被分配。
    假如S被声明为局部变量,那么S在栈上,S所指向的字符序列,在堆上。
    简单变量例如integer、Byte、Char等,全局的就在全局数据区、局部的就在栈上,变量名字就是它存放数据的地方。
      

  5.   


    根据上面说的一大堆,请理解下面的:注意,这里3楼的S是局部变量。Pointer(S) ---- 把位于栈上的S(四个字节)转换为指针类型使用,即:取S变量所在四个字节空间的内容@S         ---- S位于栈上,占四个字节,但这四个字节在具体的什么地址?@S即是。说到这里停一下,请注意,一个是四个字节的内容,一个是四个字节的位置@S[1]      ---- 这个,在前面楼层已经讲了,这是S所指向的堆内存字符序列的第一个字符的地址Pointer(P) ---- 这个,就是把P的内容读出来,与Pointer(S)一样Pointer(string((@S)^))  ---- 这个看起来复杂,实际上是写法上的重复,只是为了加深理解@S:
      @S前面已讲,是S所在栈内存的位置。因此,(@S)^就是S。于是,String((@S)^)还是S。
      于是Pointer(string((@S)^))就是Pointer(S)
      

  6.   

    另外,你或许注意到,为什么@S[1]等于Pointer(S)?不是在堆上吗?可能对于短字符串变量,Delphi直接就给放在了栈上吧。如果超过255个字符,或者使用字符串常量赋值,你就看出区别了特别提示:上面我的言论或许我不对之处,因为是边想边写的,没有仔细验证,有时间我验证一下!