zoukankan      html  css  js  c++  java
  • 长串

    String类型其实是一个指向特定格式的内存块的指针,在Delphi1中,定义一个String类型的变量的方式为:

    var
        nStr : PString;

    在Delphi后来的版本后,直接使用String关键字,但其本身仍然是一个指向串的指针:

    var
    
        nStr : String;
    
        Len : Integer;
    
    begin
    
        nStr := 'HelloWorld';
    
        Len := Sizeof(nStr);  //4
    
    end;

    Sizeof(nStr)其实是该指针的大小,并不是串的大小。判断串的大小需要用Length()方法。如果该指针为nil,则该串为空。否则则指向一个字符序列。

    在Delphi中,String类型又分为:

    ShortString, AnsiString, WideString.

    在默认情况下:

    var 
    
        nStr1 : String;    
    
        nStr2 : AnsiString;  

    使用String关键字申明的nStr1变量相当于nStr2.

    一个长串(String/AnsiString)的内部情况如下:

        偏移位置(Byte)
    
            -8                   //(-8..-4)存储一个整型的引用计数,对于常量串,这个值置为-1。
    
            -4                   //(-4..0)存储一个整型的串长度
    
            1..Length       //存储串
    
            Length + 1    //末尾追加一个NULL

    注:WideString没有引用计数,其他与之相同。

    对于两个串实现赋值

    nStr1 := nStr2;

    编译器会将其转换成两个步骤:第一先将nStr2的引用计数增加1,第二将nStr1指针置为与nStr2指针相同。

    另外值得注意的是,如果将一个串传递到某个程序中,而且不打算对该串进行修改,那么最好的方式是将该串申明为const。因为如果没有申明为const(而且,这个串你正好也不需要修改),编译器就会认定你可能会修改它,因此就会建立一个局部不可见的串变量来保存它。使用时将它的引用计数增加,等使用完了就递减。编译器为了保证该串的引用计数能被递减以释放,会增加一个try .. finally块来确保。因此,在此会略微增加程序的开销。

    如下:

    function CountOfString1(nStr : String): Integer;
    var
      i: Integer;
    begin
      for i := 0 to Length(nStr) do
        if nStr[i] = '1' then
          inc(Result);
    end;
    
    function CountOfString2(const nStr : String): Integer;
    var
      i: Integer;
    begin
      for i := 0 to Length(nStr) do
        if nStr[i] = '1' then
          inc(Result);
    end;
    
    procedure TForm1.btn1Click(Sender: TObject);
    var
      i: Integer;
      Tick : Cardinal;
    begin
      Tick := GetTickCount;
      for i := 0 to 10000000 - 1 do
        CountOfString1('HelloWorld1');
      ShowMessage(Format('%d', [GetTickCount - Tick]));  //我的机器显示大致在240-250之间
    end;
    
    procedure TForm1.btn2Click(Sender: TObject);
    var
      i: Integer;
      Tick : Cardinal;
    begin
      Tick := GetTickCount;
      for i := 0 to 10000000 - 1 do
        CountOfString2('HelloWorld1');
      ShowMessage(Format('%d', [GetTickCount - Tick]));  //我的机器显示大致在120- 130之间
    end;

     最后就是串的Pos()方法。

    该方法是返回一个子串在一个更大的串中的位置。但是,如果我们要想知道某一个字符在某个大串中的位置,使用该方法,编译器又会做一些额外的操作,如下:

    var
    
        nChar : Char;
    
        nStr : String;
    
        nPos : Integer;
    
    begin
    
        nPos := Pos(nChar, nStr);
    
    end;

    使用上面的方式查找位置,编译器会自动将这个字符转换成一个长度为1的串。转换后再调用该Pos()函数。因为要调用一个自动的而且不可见的串,所以自然在使用结束后要将其释放,这里就会额外的用到try .. finally块来确保释放该串。

    所以:

    var
    
        i, nPos : Integer;
        nChar : Char;
        nStr : String;
    
    begin
    
        for i := 1 to Length(nStr) do
    
        begin
    
            if nChar = nStr[i] then
    
            bein
    
                nPos := i;
    
                Break;
    
            end;
    
        end;
    
    end;

    使用该方式反而会比上面的方法更快一些。当然,如果本身就是要查找一个串在另一个串中的位置,也就没有这种可以略微减少开销的方式了。

    再者,如果想要在串后面追加串:

    nStr1 := nStr1 + nStr2; 

    一般我们都是这样做,使用‘+’连接符。

    但是,如果我们要在串后面追加一个字符呢:

    nStr1 := nStr1 + nChar;

    如果使用这样的方法,那么编译器还是会将这个nChar转换成串。

  • 相关阅读:
    项目选题报告答辩总结
    项目UML设计(团队)
    项目选题报告答辩总结
    第七次作业
    结对第二次
    第四次作业
    alpha冲刺4
    alpha冲刺3
    alpha冲刺2
    alpha冲刺1
  • 原文地址:https://www.cnblogs.com/Blogs-young-chan/p/5692209.html
Copyright © 2011-2022 走看看