var 
   s:string; 
   ps:Pchar; 
   b:pbyte; 
   len:integer; 
begin 
   s:=edit1.Text; //字符串 
   ps:=pchar(s); //转成pchar类型, 
   len:=length(s);//取字符串长度,占用多少字节 
   getmem(b,len);//申请内存,pchar,pbyte在使用前都必须要申请内存,因为他们是指针. 
   move(ps^,b^,len);//这里 ps^意思是pchar指向内存数据的第一个字节地址,B^是表示申请内存的第一个字节地址,这样就可以一个一个字节的移到b里去了. 
   memo1.Text:=pchar(b);//显示. 
   freemem(b); 
end; 以上代码中:为什么 move(s,b,len)不行呢?  MOVE 的第一、二两个参数到底是传值还是传址。传址的话,也不对呀,因为MOVE的原型是procedure       Move( const Source; var Dest; count : Integer ); 
{$IFDEF PUREPASCAL} 
var 
  S, D: PChar; 
  I: Integer; 
begin 
  S := PChar(@Source);//取内存地址 
  D := PChar(@Dest);//取内存地址 
  if S = D then Exit; 
  if Cardinal(D) > Cardinal(S) then 
    for I := count-1 downto 0 do 
      D[I] := S[I] 
  else 
    for I := 0 to count-1 do 
      D[I] := S[I]; 
end; 

解决方案 »

  1.   

    如果传地址,那么下句:
    S := PChar(@Source);//取内存
    D := PChar(@Dest);//取内存地址  就变成指针的地址了,这样就错了。
      

  2.   

    我记得前段时间在网上看到,其实move和copy差不多,只是名字起得。
      

  3.   

    首先纠正一下:
     getmem(b,len+1);//应当加1,因为字符串以0结尾,而Length函数是没把0计算在内的。 
      move(ps^,b^,len+1);//复制字符串,包括末尾的0再解释下Move:
    MOVE 的第一、二两个参数是传址的。
    比如正确的move(ps^,b^,len+1),在这里,ps指向的是字符串s的第一个字符所在的地址X,b指向的是分配到的内存的首地址Y,所以ps^、b^分别是X、Y,而ps、b则分别表示变量自身的地址。其实这样也是可以的:
    Move(PChar(s)^,b^,len+1);
    对于不正确的move(s,b,len+1),在这里,s表示变量自身的地址。
    注意上面的解释中用到了“在这里”的字眼,因为在不同的语境下,变量名所代表的含义可能有所区别。比如:
    自定义函数f1(p: pbyte)和f2(const p),当如下调用时:
    f1(b);//此处b表示它指向的地址
    f2(b);//此处b表示变量自身的地址
      

  4.   

    另外关于MOVE的原型,你注意编译指令{$IFDEF PUREPASCAL},断点调试会发现根本没进去,其实是走到了{$ELSE}分支:
    asm
      cmp     eax, edx
      je      @@Exit {Source = Dest}
      ...
    end;
    {$ENDIF}