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;

  • 相关阅读:
    vue集成百度UEditor富文本编辑器
    HTTPS访问站点,出现证书问题解决(转载) 规格严格
    JSSE 提供的 动态 debug 追踪模式 规格严格
    javax.net.debug 规格严格
    Oralce null 规格严格
    pipe 规格严格
    (总结)ibatis 动态传入表名和列名 规格严格
    垃圾回收算法简介 规格严格
    转载(正则表达式的分类) 规格严格
    长度为0的数组 规格严格
  • 原文地址:https://www.cnblogs.com/del88/p/6621809.html
Copyright © 2011-2022 走看看