打印本文 打印本文 关闭窗口 关闭窗口
Delphi之数组
作者:武汉SEO闵涛  文章来源:敏韬网  点击数1703  更新时间:2009/4/23 18:39:22  文章录入:mintao  责任编辑:mintao
nbsp;    Length:LongWord;              //字符串长度
        end;
        var
          k,j: AnsiString;
          P:^LongWord;
          MyAnsiString:PAnsiString;
        begin
          k:=''''I love Delphi!'''';计数器应该为1,因为刚刚分配内存,只有一个使用者
          P:=@K[1];
          Dec(P,2);
          MyAnsiString:=@(p^);
          showmessage(''''现在计数器:''''+Inttostr(MyAnsiString^.ReferencCount));
          showmessage(''''长度为:''''+Inttostr(MyAnsiString^.Length));
          j:=K;//计数器应该加1,因为j的指针指向了他,使用者又多了一个
          showmessage(''''现在计数器:''''+Inttostr(MyAnsiString^.ReferencCount));
          showmessage(''''长度为:''''+Inttostr(MyAnsiString^.Length));
          j:=''''123'''';//计数器应该减1,因为j的指针指不再指向他,使用者少了一个
          showmessage(''''现在计数器:''''+Inttostr(MyAnsiString^.ReferencCount));
          showmessage(''''长度为:''''+Inttostr(MyAnsiString^.Length));
          k:=j;//k的指针指向j的内容所在,那么这片数据的计数器再减去一个,即为0。
          //然而因该该内存区域已经被自动释放所以这里再去读数的话就是一些随机数据
          showmessage(''''现在计数器:''''+Inttostr(MyAnsiString^.ReferencCount));
          showmessage(''''长度为:''''+Inttostr(MyAnsiString^.Length));
        end;

       动态数组的回收机制原理相同,现在明白了为什么动态数组再回收时要给他赋成Nil了吧!变体型等生存期自管理的
       类型都是用这种机制来实现的.
       为什么说字符串是动态数组的一种呢?因为以上方法同样适用于动态数组。我们用动态数组自己实现一个
       AnsiString看看行不行呢?
       比如:
       Type
        PAnsiString=^TAnsiString;
        TAnsiString= record
           ReferencCount:LongWord;       //引用次数
           Length:LongWord;              //字符串长度
        end;
        var
          k,j: array of Integer;
          P:^LongWord;
          MyAnsiString:PAnsiString;
        begin
          SetLength(k,10);//计数器应该为1,因为刚刚分配内存,只有一个使用者k
          SetLength(j,10);
          P:=@K[0];
          Dec(P,2);
          MyAnsiString:=@(p^);
          showmessage(''''现在计数器:''''+Inttostr(MyAnsiString^.ReferencCount));
          showmessage(''''长度为:''''+Inttostr(MyAnsiString^.Length));
          j:=K;//计数器应该加1,因为j的指针指向了他,使用者又多了一个
          showmessage(''''现在计数器:''''+Inttostr(MyAnsiString^.ReferencCount));
          showmessage(''''长度为:''''+Inttostr(MyAnsiString^.Length));
          SetLength(j,100);//计数器应该减1,因为j的指针指不再指向他,使用者少了一个
          showmessage(''''现在计数器:''''+Inttostr(MyAnsiString^.ReferencCount));
          showmessage(''''长度为:''''+Inttostr(MyAnsiString^.Length));
          SetLength(k,100);//k内存被重新分配,那么这片数据的计数器再减去一个,即为0。
          //然而因没有使用者该内存区域已经被自动释放所以这里再去读数的话就是一些随机数据
          showmessage(''''现在计数器:''''+Inttostr(MyAnsiString^.ReferencCount));
          showmessage(''''长度为:''''+Inttostr(MyAnsiString^.Length));
        end;
       理论上来说能模拟实现AnsiString的一些功能,通过这些可以看到AnsiString不过是动态数组的一种形式。
     3.WideString:宽字符串,由WideChar组成,以Nil结尾.
       Type
        TWideString=record
           allocSiz: LongWord;//分配的大小
           Length:LongWord;         //字符串长度
           Data:array[1..(Length+1)] of WideChar;
        end;
        有结构可以看出,WideString和AnsiString很类似,但是他没有回收机制。不能进行生存期自管理。
        但是在处理上还是较C\C++效率高上许多。     
     4.Pchar:与其说成是字符串到不如说他是指针更准确一些。
        Type
         TPchar=^Char;
       Pchar是为了和C\++兼容的实际上它是指向字符的指针。从这个字符开始到后面第一个NULL字符为止都是
       Pchar字符串的内容,也就是说PChar是它内容的首地址,因为Pchar并非结构而是一种指针所以Pchar的
       下限是0.
       var
         A:Pchar;
       ...
         A:=''''1234567890'''';
         A[0]:=''''a'''';//这一句是合法的
      
       看看如下代码就明白了:
        var
          k:array of char;
          p:Pchar;
          i:Integer;
        begin
          SetLength(k,20);
          FillMemory(@k[0],Length(k),Byte(''''A''''));
          i:=3;  //i只要比20小,大于等于0,随你调整看看不同的结果。
          k[i]:=#0;
          p:=@k[0];
          showmessage(p);
        end;
       
其它:数组在所有的编程语言中都是一个很重要的数据类型(不过Java的数组使用类来实现的)。
     是应用很广泛的一种技术。 如果你见过下列语法:
    
     TA=Class(TXXX)
     ...
     public
       procedure Exec; Overload;
       procedure Exec(Value:Boolean); Overload;
     end;
     一定会知道这是应用了这是重载。但是有没有想过在对象的内部机制中重载是如何实现的呢?
     在内部实际上它是一个函数的数组(内部由表来实现)。当调用时会根据参数的不同来决定调用哪一个。
    
     附:
     几条数组常用的函数
     High(),Low()取数组的上下界    
    
    

上一页  [1] [2] 

打印本文 打印本文 关闭窗口 关闭窗口