var
  S: string;
  PStr: PChar;
begin
  S := 'abcdefg';
  PStr := @S[1];
  ShowMessage(PStr);
end;
S后面为什么还要加上[1]

解决方案 »

  1.   

    很奇怪的问题,其与Pointer又不一样
      

  2.   

    我想是类型匹配吧,PChar是Char的地址,而用Pointer,可以取s地址再显示出来;测试发现,若用PChar取s地址则显示不全,而PChar可取s中任何一个字符的开始地址并显示。期侍对此熟之兄弟能说明一些
      

  3.   

    Delphi 中String的标注是从1开始的.
      

  4.   

    1. ShowMessage();函数的参数要求是String类型的, ShowMessage(PStr);中的PStr是PChar类型的,Delphi编译器在编译时,会隐式地进行类型转换,即:ShowMessage(String(PStr));2. S: string; 
    这个String类型的内存分配是按Pascal字符串的方式进行的,第[0]个元素存放的是字符串的长度值,从第[1]个元素开始存放的是字符串中的字符内容。
    由于默认情况下String等效于AnsiString,而编译器是不允许访问AnsiString类型的第[0]个元素的,所以代码中不能出现S[0]的写法。改成这样,就能访问S[0]了:
    var
      S: ShortString;
    begin
      S := 'abcdefg';
      ShowMessage(IntToStr(ord(S[0])));
    end;3.  PStr := @S[1];
    将PChar类型的PStr指针指向S[1],PChar是C的字符串格式(以0号字符结尾),由于S := 'abcdefg';在赋值时并未写成S := 'abcdefg'#0;,所以楼主的这段测试代码隐藏着一个Bug。下面的测试代码更能说明问题:
    var
      S: String;
      PStr: PChar;
    begin
      S := 'abcdefg'#0'xyz';
      ShowMessage(IntToStr(Length(S)));        //显示11
      PStr := @S[1];
      ShowMessage(IntToStr(Length(PStr)));     //显示7
    end;注:ShowMessage(IntToStr(Length(PStr))); 其实被编译器理解为ShowMessage(IntToStr(Length(String(PStr))));
      

  5.   

    楼主的这个测试,实际上体现的是Pascal字符串类型与C字符串类型之间的区别。掌握这些区别对于经常调用Windows API的Pascal/Delphi开发者来说是非常重要。
      

  6.   

    string[0]保存的是字符串的长度
    PChar则是遇到#0就认为字符串结束。
    string[1]是字符串第一个有效数据的开始。
    例如
    strA: string;
    begin
        strA := 'abcd';
        showmessage(strA[1]);
    end;
    //显示为a