关于SizeOfLength
Posted 不能富贵难成大器皆因懒, 胸无大志庸庸碌碌只为闲。
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于SizeOfLength相关的知识,希望对你有一定的参考价值。
结论:
到底什么时候用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;
以上是关于关于SizeOfLength的主要内容,如果未能解决你的问题,请参考以下文章
关于js----------------分享前端开发常用代码片段
springcloud报错-------关于 hystrix 的异常 FallbackDefinitionException:fallback method wasn't found(代码片段