zoukankan      html  css  js  c++  java
  • 关于SizeOf、Length

    结论:

    到底什么时候用Length,SizeOf呢,我总结下使用Length,Sizeof的场景

    1.Length(静态数组或动态数组)----没有问题

    2.Length(string/shortstring/ansistring/utf8string) --- 任何string都不能用,以防错误,那么该如何计算一个字符串中字符的个数呢,用我师傅的CharCountA/w/u如下图;

    3.SizeOf(静态数组) ---- 返回数组占用的总的字节数如:array[0..5] of Byte ; array[0..5] of integer;

    4.SizeOf(动态数组、或任何堆栈式存储方式的东东如:任何ansistring/utf8string/string等) ---- 错误,对于堆栈式存储结构它返回的是栈中指针的内存大小,32位程序的话始终是4;

    5.SizeOf(基本数据类型如:Char/Integer/Cardinal/Boolean等不包含String) ----- 可以得到数据类型占用的字节数;

    6.SizeOf(无堆栈存储方式的Record)

    ----------------------------------------------------------------------------------------------------------------------------------------

    procedure TForm4.Button1Click(Sender: TObject);
    var
      a: AnsiString;{本地系统GBK编码}
      b: UnicodeString;
      c: UTF8String;
      d: WideString;{WideString的编码也是Unicode的,与String的区别是没有引用计数,编译器会自动识别处理}
      e: string;{UnicodeString}
      a1,b1,c1,d1,e1: TBytes;
    begin
      a := 'a好';//好---2个字节
      b := 'a好';//好---2个字节
      c := 'a好';//好---3个字节
      d := 'a好';//好---2个字节
      e := 'a好';//好---2个字节
    
    
      //知识点1:首先AnsiString(本地GBK)、UnicodeString、UTF8String、WideString都是兼容ASCII码的
      //知识点2:SizeOf 都等于4的原因是, String是栈堆存储的, SizeOf算的是栈中指针的字节数。
      //知识点3: Length 返回的是字节数,但是对于Unicode编码的字符串而言(String,UnicodeString,WideString),返回的是字节数除以2
      //知识点4:widestring也是unicode编码的.
      Memo1.Lines.Clear;
      Memo1.Lines.Add('AnsiString:' + sLineBreak + Length(a).ToString + sLineBreak + SizeOf(a).ToString);
      Memo1.Lines.Add('UnicodeString:' + sLineBreak + Length(b).ToString + sLineBreak + SizeOf(b).ToString);
      Memo1.Lines.Add('UTF8String:' + sLineBreak + Length(c).ToString + sLineBreak + SizeOf(c).ToString);
      Memo1.Lines.Add('WideString:' + sLineBreak + Length(d).ToString + sLineBreak + SizeOf(d).ToString);
      Memo1.Lines.Add('string:' + sLineBreak + Length(e).ToString + sLineBreak + SizeOf(e).ToString);
    
    
      //让我们看看堆中的数据到底有几个字节数以及如何存储的
      a1 := TEncoding.ANSI.GetBytes(a);
      b1 := TEncoding.Unicode.GetBytes(b);
      c1 := TEncoding.UTF8.GetBytes(c);
      d1 := TEncoding.Unicode.GetBytes(d);
      e1 := TEncoding.Unicode.GetBytes(e);
    end;
    
    procedure TForm4.Button2Click(Sender: TObject);
    var
      //a: AnsiString[10];报错,不能这样定义
      //b: UnicodeString[10];报错,不能这样定义
      //c: UTF8String[10];报错,不能这样定义
      //d: WideString[10];报错,不能这样定义
      a: string[10];
      b: ShortString;{相当于 String[255]}
      a1,b1: TBytes;
    begin
      a := 'a好';
      b := 'a好';
    
      //知识点1:对于定长字符串也是堆栈的方式存储的
      //知识点2:string的下标是从1开始的,所以string[10] 就是 1..10个元素,那么为什么SizeOf等于11呢,因为定长字符串会多出一个首字节来记忆字符串的实际长度
      //知识点3: 虽然定长字符串也是堆栈方式存储的,但是SizeOf返回的结果与变长字符串不同,返回的是实际占用的字节数.
      Memo1.Lines.Clear;
      Memo1.Lines.Add('string[10]:' + sLineBreak + Length(a).ToString + sLineBreak + SizeOf(a).ToString);
      Memo1.Lines.Add('ShortString:' + sLineBreak + Length(b).ToString + sLineBreak + SizeOf(b).ToString);
    
      //让我们看看堆中的数据到底有几个字节数以及如何存储的
      a1 := TEncoding.Unicode.GetBytes(a);
      b1 := TEncoding.Unicode.GetBytes(b);
    end;
    
    procedure TForm4.Button3Click(Sender: TObject);
    var
      a: array[0..5] of Byte;
      b: TBytes;
    begin
      //构造动态数组
      b := WideBytesOf('abc您好');
    
      //知识点1:静态数组是仅仅栈内存储的,而动态数组是堆栈方式存储的
      //知识点2:观察SizeOf的结果你会发现,SizeOf对应静态数组而言返回的就是占用的字节数,对于动态数组而言返回的是指针占用的字节数
      Memo1.Lines.Clear;
      Memo1.Lines.Add('静态数组:' + sLineBreak + Length(a).ToString + sLineBreak + SizeOf(a).ToString);
      Memo1.Lines.Add('动态数组:' + sLineBreak + Length(b).ToString + sLineBreak + SizeOf(b).ToString);
    
    end;

     

     

    type
        r1 = record
        age: Integer;
        sex: Boolean;
        year: Word;
      end;
    
      r2 = record
        name: string;
        age: Integer;
        sex: Boolean;
        year: Word;
      end;
    
    
    procedure TForm4.Button4Click(Sender: TObject);
    var
      a: r1;
      b: r2;
    begin
      a.age := 10;
      a.sex := True;
      b.name := 'xiaoli';
    
    
      //知识点1:含有堆栈存储的结构不能用SizeOf来去字节的大小;比如name是指针
      //知识点2:这里牵涉到字节对齐的问题,具体可以百度,没有必要知道这个是编译器的事。
      Memo1.Lines.Clear;
      Memo1.Lines.Add('不含堆栈结构:' + SizeOf(r1).ToString); //8
      Memo1.Lines.Add('含堆栈结构:' + SizeOf(r2).ToString);//8 + 4 = 12 不可用于SizeOf
    end;

  • 相关阅读:
    BZOJ 3132: 上帝造题的七分钟 树状数组+差分
    PAT Advanced 1006 Sign In and Sign Out (25 分)
    PAT Advanced 1011 World Cup Betting (20 分)
    PAT Basic 1032 挖掘机技术哪家强 (20 分)
    PAT Basic 1028 人口普查 (20 分)
    PAT Basic 1004 成绩排名 (20 分)
    大数据数据库HBase(二)——搭建与JavaAPI
    PAT Advanced 1009 Product of Polynomials (25 分)(vector删除元素用的是erase)
    PAT Advanced 1002 A+B for Polynomials (25 分)(隐藏条件,多项式的系数不能为0)
    PAT Basic 1041 考试座位号 (15 分)
  • 原文地址:https://www.cnblogs.com/del88/p/6621809.html
Copyright © 2011-2022 走看看