一、Delphi 2009 之前的字符串(不支持 Unicode):

  Delphi 2009 之前的字符串分为 3 种:ShortString、AnsiString、WideString。

【ShortString】

  ShortString 是一种比较古老的 Pascal 字符串格式,它最多只能容纳 255 个字节的字符。当我们声明一个 ShortString 类型的变量时,Delphi 会自动申请 256 个字节的内存空间给该变量,其中第一个字节用来存放字符串的长度,后面的 255个字节用来存放字符串内容,如果字符串的长度不够 255 个字节,则有多少字符就用多少内存,后面未用到的内存清零。

var
  SStr: ShortString;

  上面的声明就使 SStr 拥有了 256 个字节的内存空间:

Sizeof(SStr); { = 256; }

  直到 SStr 不再被使用时,Delphi 会自动释放 SStr 所占用的内存空间。

  我们还可以用下面的方式来声明 ShortString 类型的变量:

var
  SStr: string[16];

  这样,我们就声明了一个只能容纳 16 个字节内容的 ShortString 字符串,加上一个字节用来存放字符串的长度,SStr 一共占用 17 个字节的内存空间:

Sizeof(SStr); { = 17; }

  我们可以像使用字节数组(array of byte)那样来使用 ShortString,比如我们可以用下标来访问 ShortString 中的各个字符,可以用 High 和 Low 函数来获取 ShortString 的上限位置和下限位置。由于字符串的第一个字节存放的是字符串的长度,所以 SStr[0] 存放的是字符串的长度,例如:

var
  SStr: string[16];
begin
  SStr := 'ABC';
{ 此时:
  Ord(SStr[0]);  // = 3   字符串长度为 3
  SStr[1];       // = 'A' 第一个字符为 A
  SStr[2];       // = 'B' 第二个字符为 B
  SStr[3];       // = 'C' 第三个字符为 C
  SStr[4];       // = #0  其余位置清零 #0
  ……           //       其余位置清零 #0
  SStr[255];     // = #0  其余位置清零 #0
  High(SStr);    // = 16  上限位置为 16
  Low(SStr);     // = 0   下限位置为 0 }
end;

  接下来,我们来看看 SStr 的指针情况。

----------

{ 在一个空白窗体上放置一个 TMemo 和一个 TButton }
procedure TForm1.Button1Click(Sender: TObject);
var
  SStr: ShortString;

pS: Pointer;
  pS1: Pointer;
begin
  SStr := 'ABC';

pS := Addr(SStr);        { 字符串变量 SStr 的地址 }
  pS1 := Addr(SStr[0]);    { 字符串的首地址 }

Memo1.Clear;
  Memo1.Lines.Add(IntToStr(Integer(pS)));  { 在我的电脑中显示为:1242240 }
  Memo1.Lines.Add(IntToStr(Integer(pS1))); { 在我的电脑中显示为:1242240 }
end;

----------

  上面的代码说明变量 SStr 的地址就是“存放字符串的内存块”的地址。这和后面讲到的 AnsiString 和 WideString 不同。

【AnsiString】

  AnsiString 是一种动态分配内存的字符串,也就是说当我们声明一个 AnsiString 时,它并不占用内存空间,比如:

var
  AStr: AnsiString;

  此时字符串的长度为 0,不占用内存空间:

Length(AStr);  { = 0 }

  这里为什么不用 Sizeof(AStr); 而用 Length(AStr); 因为 AStr 和 ShortString 不同,变量 AStr 的地址并不是“存放字符串的内存块”的地址,变量 AStr 中存放的只是一个指针,指向“存放字符串的内存块”,我们通过变量 AStr 可以找到“存放字符串的内存块”,请看下面的代码:

----------

{ 在一个空白窗体上放置一个 TMemo 和一个 TButton }
procedure TForm1.Button1Click(Sender: TObject);
var
  AStr: AnsiString;

pA: Pointer;
  pA1: Pointer;
begin
  AStr := 'ABC';

pA := Addr(AStr);       { 字符串变量 AStr 的地址 }
  pA1 := Addr(AStr[1]);   { “存放字符串的内存块”的地址。Delphi 不允许访问 AStr[0] }

Memo1.Clear;
  Memo1.Lines.Add(IntToStr(Integer(pA)));  { 在我的电脑中显示为:1242504 }
  Memo1.Lines.Add(IntToStr(Integer(pA1))); { 在我的电脑中显示为:17539780 }
end;

----------

  从上面的代码中可以看出,字符串变量 AStr 的地址和“存放字符串的内存块”的地址是不一样的。所以用 Sizeof(AStr) 无法获取字符串的大小,只能获取一个指针的大小,永远为 Sizeof(Pointer);

  刚才说了,AnsiString 变量在刚声明的时候是不分配内存的,所以就不能使用 AStr[1],因为 AStr[1] 是指“被分配的内存块”中的第一个字符,而“内存块”根本就没有分配,哪来的第一个字符?所以在使用 AStr[1] 之前首先要判断 Length(AStr) 是否为 0,若为 0,就表示内存块未分配,就不能使用 AStr[1]。

  那什么时候 AStr 才分配内存呢?当我们给 AStr 赋值的时候,Delphi 就给 AStr 分配内存,例如:

----------
var
  AStr: AnsiString;     { 此时 AStr 未分配内存 }
begin
  AStr := 'ABC';        { 此时 Delphi 给 AStr 分配了三个字节的内存用来存放 'ABC' }
  ShowMessage(AStr[1]); { 这时就可以使用 AStr[1] 了 }
  AStr := 'ABCDEF';     { 此时 Delphi 增大字符串的内存空间来存放更多字符 }
  AStr := '';           { 此时 AStr 将刚分配的内存全部释放 }
  ShowMessage(AStr[1]); { 错误,因为此时未分配内存,所以不可以使用 AStr[1] }
end;

----------

  那么变量 AStr 和“存放字符串的内存块”之间是什么关系呢?变量 AStr 中存放的其实是一个指针,指向“存放字符串的内存块”。通过下面的代码可以很好的理解这个问题:

----------

{ 在一个空白窗体上放置一个 TMemo 和一个 TButton }
procedure TForm1.Button1Click(Sender: TObject);
var
  AStr: AnsiString;

pA: Pointer;      { 变量 AStr 的地址 }
  pA1: Pointer;     { 字符串中第一个字符的地址(即:内存块的地址) }
  pAP: Pointer;     { 变量 AStr 中所存放的指针 }
begin
  AStr := 'ABC';    { 申请三个字节的内存块用来存放 'ABC' }

pA  := Addr(AStr);    { 获取变量 AStr 的地址 }
  pA1 := Addr(AStr[1]); { 获取内存块的地址 }
  pAP := Pointer(AStr); { 获取变量 AStr 中所存放的指针 }

Memo1.Clear;
  Memo1.Lines.Add(IntToStr(Integer(pA)));   { 变量 AStr 的地址 }
  Memo1.Lines.Add(IntToStr(Integer(pA1)));  { 内存块的地址 }
  Memo1.Lines.Add(IntToStr(Integer(pAP)));  { 变量 AStr 中所存放的指针 }
end;

----------

{ 运行结果 }
1242504      { 变量 AStr 的地址 }
17539780     { 内存块的地址 }
17539780     { 变量 AStr 中所存放的指针 }

----------

  由此可见 AStr 中存放的只是一个指针,指向“存放字符串的内存块”,我们可以通过 Pointer(AStr) 来得到这个内存块的地址。

  上面的代码有一个奇怪的地方,就是将 pA1 := Addr(AStr[1]); 和 pAP := Pointer(AStr); 两行代码的前后位置对调一下,运行结果就不同了(测试环境:Delphi XE2),下面是对调以后的运行结果:

----------

{ 对调以后的运行结果 }
1242504      { 变量 AStr 的地址 }
17539780     { 内存块的地址 }
5327792      { 变量 AStr 中所存放的指针 }

----------

  这或许是 Delphi 对字符串优化所造成的结果(Delphi 的 copy-on-write 技术),当我们仅仅是读取该字符串时,它的地址就是刚赋初始值时的地址(5327792),而当我们要修改字符串时( pA1 := Addr(AStr[1]) 也被认为是用户将要通过指针修改字符串),Delphi 就会把该字符串复制到新的地方(17539780)给用户修改并继续使用。如果“旧地址中的字符串”还同时被其它变量引用,比如 AStr := 'ABC' 之后又 AStr2 := AStr,则保留旧地址,供 AStr2 继续使用,如果旧地址不再被其它变量使用,则将旧地址中的字符串全部释放。 )

  为了检验以上说法,我们用下面的代码再测试一次,这次,我们将 AnsiString 定义为常量,不允许修改,看看结果如何:

----------

{ 在一个空白窗体上放置一个 TMemo 和一个 TButton }
procedure TForm1.Button1Click(Sender: TObject);
const
  AStr: AnsiString = 'ABC';
var
  pA: Pointer;      { 变量 AStr 的地址 }
  pA1: Pointer;     { 字符串中第一个字符的地址(即:内存块的首地址) }
  pAP: Pointer;     { AStr 中所存放的指针 }
begin
  pA  := Addr(AStr);    { 获取变量 AStr 的地址 }
  pAP := Pointer(AStr); { 获取变量 AStr 中所存放的指针(放前面) }
  pA1 := Addr(AStr[1]); { 获取内存块的地址(放后面) }

Memo1.Clear;
  Memo1.Lines.Add(IntToStr(Integer(pA)));   { 变量 AStr 的地址 }
  Memo1.Lines.Add(IntToStr(Integer(pA1)));  { 内存块的地址 }
  Memo1.Lines.Add(IntToStr(Integer(pAP)));  { 变量 AStr 中所存放的指针 }
end;

----------

{ 此时的运行结果 }

5379472      { 变量 AStr 的地址 }
5327460      { 内存块的地址 }
5327460      { 变量 AStr 中所存放的指针 }

----------

  字符串的地址没有发生变化,这验证了刚才我们说的 Delphi 的 copy-on-write 技术。这也解释了为什么提倡大家在不修改字符串内容的情况下,尽量将字符串声明为常量(比如函数的字符串参数),因为常量不会触发 Delphi 的 copy-on-write技术,增加代码的执行效率。

  接下来有必要对 Length 函数做一下说明,Length 函数对于 ShortString 和 AnsiString 来说,都是指“字符串中的字节数(而不是字符数)”,请看下面的例子:

----------

{ 在一个空白窗体上放置一个 TMemo 和一个 TButton }
procedure TForm1.Button1Click(Sender: TObject);
var
  SStr: ShortString;
  AStr: AnsiString;
begin
  Memo1.Clear;

SStr := '123你好吗';  { 一共 6 个字符 }
  AStr := '123你好吗';  { 一共 6 个字符 }

Memo1.Lines.Add(IntToStr(Length(SStr)));    { 结果 9 }
  Memo1.Lines.Add(IntToStr(Length(AStr)));    { 结果 9 }
end;

----------

  因为一个英文字符只占用 1 个字节的内存空间,而一个汉字要占用 2 个字节的内存空间,所以 SStr 和 AStr 都用了 9 个字节的内存空间来存放字符串。如果此时你使用 AStr[4] 来获取汉字“你”,那么只能获取半个汉字,此时的 AStr[4] 是 AnsiChar 类型(单字节)。所以用 AnsiString 处理汉字是很麻烦的,我们一般用 WideString 来处理带有汉字的字符串。

  关于 Delphi 不允许访问 AStr[0],其实 AnsiString 和 ShortString 有着类似的结构,也就是说在 AnsiString 字符串的前面也有一个数据区用来保存 AnsiString 的长度(字节数),这个数据区就是字符串之前的 4 个字节,我们可以通过指针来访问这个区域,而再之前的 4 个字节中还存放着字符串的引用计数,标识着这个字符串被几个字符串变量所引用。在 Delphi 7 的 system 单元中可以找到字符串结构的定义:

StrRec = packed record
  refCnt: Longint;   { 引用计数 }
  length: Longint;   { 字符串长度 }
end;

请看下面的代码:

----------

{ 在一个空白窗体上放置一个 TMemo 和一个 TButton }
procedure TForm1.Button1Click(Sender: TObject);
var
  AStr: AnsiString;
  P: PCardinal;    { Sizeof(Cardinal) = 4 字节 }
begin
  Memo1.Clear;

SetLength(AStr, 65530);
  P := PCardinal(AStr);

Dec(P); { 向前移动 4 个字节 }
  Memo1.Lines.Add(IntToStr(P^));    { 结果 65530   字符串长度 }
  Dec(P); { 再向前移动 4 个字节 }
  Memo1.Lines.Add(IntToStr(P^));    { 结果 1       引用计数 }
end;

----------

  从上面的结果可以看出,字符串的长度为 65530,引用计数为 1。

  关于 AnsiString 中可以存放的内容,有人说 AnsiString 中存放的是以 #0 结尾的字符串,和 C 语言的字符串类似,这样理解不准确,因为 AnsiString 中可以存放多个 #0 字符,#0 并不一定代表字符串的结尾。例如:

----------

{ 在一个空白窗体上放置一个 TMemo 和一个 TButton }
procedure TForm1.Button1Click(Sender: TObject);
var
  AStr, AStr2: AnsiString;
  I: Integer;
begin
  Memo1.Clear;

SetLength(AStr, 10);  { 在 AStr 中存放 10 个 #0 字符 }
  for I := 1 to 10 do
    AStr[I] := #0;

AStr2 := AStr;        { 看看赋值的过程中会不会发生字符丢失 }
  AStr2[5] := 'A';
  Memo1.Lines.Add(IntToStr(Length(AStr2)));    { 结果 10,没有丢失字符 }
end;

----------

  也就是说 AnsiString 可以直接当内存来使用,它不只可以存放字符,而是可以存放任何东西,你甚至可以将一个图片的数据存入 AnsiString 的内存块中。用 AnsiString 代替内存使用有一个好处,就是 Delpih 会帮你管理这个内存,在你不需要使用该内存块的时候,Delphi 会自动帮你释放。

  但是这样的字符串不能和 PAnsiChar 类型一起使用,因为 PAnsiChar 才是真正的以 #0 结尾的字符串(我们刚才不是说了 AnsiString 其实就是一个指针吗,PAnsiChar 也是一个指针,在用法上和 AnsiString 有很多相同的地方),当你把上面的字符串赋值给一个 PAnsiChar 变量时,PAnsiChar 只会读取第一个 #0 之前的内容,而把第一个 #0 之后的所有内容都丢弃掉。请看下面的代码:

----------

{ 在一个空白窗体上放置一个 TMemo 和一个 TButton }
procedure TForm1.Button1Click(Sender: TObject);
var
  AStr: AnsiString;
  pAStr: PAnsiChar;
  I: Integer;
begin
  Memo1.Clear;

SetLength(AStr, 10);
  for I := 1 to 10 do
    AStr[I] := #0;

pAStr := 'ABC';
  Memo1.Lines.Add(IntToStr(Length(pAStr)));    { 结果 3 }

pAStr := PAnsiChar(AStr);
  Memo1.Lines.Add(IntToStr(Length(pAStr)));    { 结果 0 }

pAStr := #0#0#0;
  Memo1.Lines.Add(IntToStr(Length(pAStr)));    { 结果 0 }
end;

----------

  好了,总结一下 AnsiString:

  AnsiString 变量只是一个指针,指向一个内存块,这个内存块用来存放实际的字符串。AnsiString 所指向的内存是动态分配的,如果 AnsiString 中未存放任何字符串,则 AnsiString 指向 nil。

  虽然 AnsiString 变量并不是真正的内存块,只是一个指针,但是我们仍然可以通过下标的方式来访问内存块中的字符。下标必须从 1 开始,Delphi 不允许 AnsiString 和 WideString 使用下标 0。

  我们可以通过如下方式访问到 AStr 所指向的内存块地址:

@AStr[1]
Pointer(AStr)

  我们可以通过如下方式访问到 AStr 所指向的内存块中的第一个字符、第二个字符、第三个字符:

AStr[1]、AStr[2]、AStr[3]
PAnsiChar(AStr)^ 、(PAnsiChar(AStr)+1)^ 、(PAnsiChar(AStr)+2)^

  PAnsiChar 类型和 AnsiString 类型之间可以很容易的相互转换。不过编译器在编译的时候会给出警告(不是错误)。例如:

----------

{ 在一个空白窗体上放置一个 TMemo 和一个 TButton }
procedure TForm1.Button1Click(Sender: TObject);
var
  AStr: AnsiString;
  pAStr: PAnsiChar;
begin
  Memo1.Clear;

AStr := 'ABC';
  pAStr := PAnsiChar(AStr);
  Memo1.Lines.Add(AStr);
  Memo1.Lines.Add(pAStr);

Memo1.Lines.Add('');

pAStr := '123';

AStr := pAStr;
  Memo1.Lines.Add(AStr);
  Memo1.Lines.Add(pAStr);
end;

----------

  关于 Length 函数,Length 函数对于 ShortString 和 AnsiString 来说返回的是它们所存放的字符串的字节数,而不是字符数。

  在 AnsiString 的字符串之前的 4 个字节中存放着字符串的总长度(总字节数),再之前的 4 个字节中存放着字符串的引用计数。

  AStr[n] 只能返回半个汉字,所以用 AnsiString 处理汉字是很麻烦的,我们一般用 WideString 来处理带有汉字的字符串。

  Delphi 对 AnsiString 和 WideString 都使用了 copy-on-write 技术,所以当我们不准备修改字符串的内容时,最好将字符串声明为常量,以提高程序的执行效率。

  Delphi 中的 AnsiString 可以直接当做内存来使用,如果你愿意这么用的话,Delphi 会帮你管理这块内存。申请内存很方便,直接 SetLength 就可以了。用完了 Delphi 会帮你释放。但此时 AnsiString 不能和 PAnsiChar 一起使用。要得到内存的地址,可以使用 Pointer(AStr)。

【WideString】

  WideSting 和 AnsiString 的用法基本一样,也是动态分配内存。所不同的是,WideString 所存储的任何字符(不管是英文还是汉字)都是使用 2 个字节,但是 WideString 没有引用计数。其实 WideString 是为了方便使用 COM 而产生的,也就是 BSTR 字符串。BSTR 没有引用计数,效率较低。

  与 WideString 相对应的类型有 WideChar,用法与 AnsiChar 一样。还有 PWideChar,用法与 PAnsiChar 一样。

  Length 函数对于 WideString 来说,返回的就是字符数,而不是字节数,要获取 WideString 的字节数,直接把 Length 的返回值乘以 2 就可以了。

  对于如下代码而言:

----------

var
  WStr: WideString;
begin
  WStr := '123你好吗'
end;

----------

  WStr[1] 就表示字符“1”,WStr[4] 就表示字符“你”,只不过此时的 WStr[1] 是 WideChar 类型(双字节)。

二、Delphi 2009 之后的字符串(开始全面支持 Unicode):

  Delphi 2009 之后又加入了一种新的字符串:UniodeString,并且对字符串的结构也做了改动,增加了 codePage 和 elemSize 域。下面是 System 单元中定义的字符串结构:

PStrRec = ^StrRec;
StrRec = packed record
  codePage: Word;   // 代码页:Unicode、UTF-8、UTF-16、GB2312
  elemSize: Word;   // 元素大小:一字符占几个字节
  refCnt: Longint;  // 引用计数:字符串被几个字符串变量使用
  length: Longint;  // 字符串长度:字节数
end;

  这个结构只用于 AnsiString 和 UnicodeString,也就是说在 AnsiString 和 UnicodeString 的字符串之前的 4 个字节存放的是字符串长度,再之前的 4 个字节存放的是字符串的引用计数,再之前的 2 个字节存放的是元素大小,再之前的 2 个字节存放的是字符串的代码页。而 WideString 依然是原来的样子,没有变化。所以我们以后可以直接使用 UnicodeString 来处理汉字。

  在 system 单元中还定义了 UTF8String 和 UCS4String 类型的字符串,定义如下:

UTF8String = type AnsiString(65001);
UCS4String = array of UCS4Char;  { UCS4Char = type LongWord; }

  除此之外,Delphi 还定义了 RawByteStrng 类型的字符串,定义如下:

RawByteString = type AnsiString($ffff);

  关于RawByteStrng 类型:在将 AnsiString 格式的字符串赋值给 UTF8String 格式的字符串时,Delphi 会自动进行格式转换(还有其它格式的自动转换),所以,如果我们有一个函数的参数需要接收各种类型的字符串时,那么就很难实现,因为在传递参数的时候,Delphi 就会自动进行格式转换,所以,Delphi 定义了 RawByteString 类型,这种类型的变量在接收任何格式的字符串时,都会保持源字符串的内存格式,不做任何改动。

【string】

  我们平时经常使用的字符串类型是 string 类型,很少直接使用 AnsiString 或 UnicodeString,那么 string 是什么类型呢?

  string 类型根据编译参数的不同,所代表的含义也不同,或者说根据 Delphi 版本的不同,所代表的含义也不同,在 Ansi 版本(Delphi 2009 之前)中,string 就代表 AnsiString,而在 Unicode 版本(Delphi 2009 之后)中,就代表 UnicodeString。

  同样的 Char 在 Ansi 版本中就代表 AnsiChar,在 Unicode 版本中就代表 WideChar。PChar 在 Ansi 版本中就代表 PAnsiChar,在 Unicode 版本中就代表 PWideChar。

  在 Delphi 的 Unicode 版本中有一个新的函数 ByteLength 用来获取字符串的字节数。但是这个函数只能用于 string 类型的变量,我们看一下它的源代码就知道为什么了。

----------

function ByteLength(const S: string): Integer;
begin
  Result := Length(S) * SizeOf(Char);
end;

----------

  这个函数会根据不同的编译条件产生不同的计算结果,所以只能配合 string 使用。如果你将它用于 AnsiSting 或 UnicodeString 型变量,则在不同的编译条件下,有可能会出现错误。请看下面的代码:

----------

{ 在一个空白窗体上放置一个 TMemo 和一个 TButton }
procedure TForm1.Button1Click(Sender: TObject);
var
  SStr: ShortString;
  AStr: AnsiString;
  UStr: UnicodeString;
  WStr: WideString;
  Str: string;
begin
  SStr := '123你好吗';
  AStr := '123你好吗';
  UStr := '123你好吗';
  WStr := '123你好吗';
  Str  := '123你好吗';

Memo1.Clear;
  Memo1.Lines.Add(IntToStr(Length(SStr)));      { 结果 9  }
  Memo1.Lines.Add(IntToStr(Length(AStr)));      { 结果 9  }
  Memo1.Lines.Add(IntToStr(Length(UStr)));      { 结果 6  }
  Memo1.Lines.Add(IntToStr(Length(WStr)));      { 结果 6  }
  Memo1.Lines.Add(IntToStr(Length(Str)));       { 结果 6  }

Memo1.Lines.Add(IntToStr(ByteLength(SStr)));  { 结果 12 }
  Memo1.Lines.Add(IntToStr(ByteLength(AStr)));  { 结果 12 }
  Memo1.Lines.Add(IntToStr(ByteLength(UStr)));  { 结果 12 }
  Memo1.Lines.Add(IntToStr(ByteLength(WStr)));  { 结果 12 }
  Memo1.Lines.Add(IntToStr(ByteLength(Str)));   { 结果 12 }
end;

http://www.cnblogs.com/PocketZ/archive/2013/03/26/2983583.html

Delphi 中的字符串(还解释了shortstring)good的更多相关文章

  1. 关于Delphi中的字符串的浅析(瓢虫大作,里面有内存错误的举例)

    关于Delphi中的字符串的浅析 只是浅浅的解析下,让大家可以快速的理解字符串. 其中的所有代码均在Delphi7下测试通过. Delphi 4,5,6,7中有字符串类型包括了: 短字符串(Short ...

  2. 关于Delphi中的字符串的详细分析

    关于Delphi中的字符串的详细分析   只是浅浅的解析下,让大家可以快速的理解字符串. 其中的所有代码均在Delphi7下测试通过. Delphi 4,5,6,7中有字符串类型包括了: 短字符串(S ...

  3. Delphi中常用字符串处理函数

    .copy(str,pos,num) 从str字符串的pos处开始,截取num个字符的串返回. 假设str为,)=,)='def' .concat(str1,str2{,strn}) 把各自变量连接起 ...

  4. Delphi中String类型原理介绍

    Delphi中字符串的操作很简单,但幕后情况却相当复杂.Pascal传统的字符串操作方法与Windows不同,Windows吸取了C语言的字符串操作方法.32位Delphi中增加了长字符串类型,该类型 ...

  5. delphi XE的字符串处理

    最近用delphi xe做了个东西,因为以前一直使用Delphi 7做开发,delphi 7 到delphi XE有了很大的变化,最大的变化就是对Unicode的支持,所以刚开始使用DELPHI XE ...

  6. Delphi中array of const应用

    Delphi的Format函数大家都用得很多,第二个参数用着确实很方便.最近在数据库开发应用中需要自己创建一个带array of const参数的函数,对于常用的类型String,Integer,Po ...

  7. Delphi中stringlist分割字符串的用法

    Delphi中stringlist分割字符串的用法 TStrings是一个抽象类,在实际开发中,是除了基本类型外,应用得最多的. 常规的用法大家都知道,现在来讨论它的一些高级的用法. 1.CommaT ...

  8. Delphi 中Format的字符串格式化使用说明(转)

    源:Delphi 中Format的字符串格式化使用说明(转) 一.Format函数的用法 Format是一个很常用,却又似乎很烦的方法,本人试图对这个方法的帮助进行一些翻译,让它有一个完整的概貌,以供 ...

  9. delphi 中字符串与16进制、10进制转换函数

      //字符串转成16进制代码function strToHexStr(str:string):string;varc:char;ss:string;i:integer;beginwhile str& ...

随机推荐

  1. IT从业人员关注哪些问题

    技术人员关注的问题非常多,但常见的至少有以下6种.特此整理,抓住核心问题,解决它. 一个人的精力和时间往往非常有限,能把核心问题都解决到位就是成功. 1.职业规划 大家从读小学开始,就是在为职业规划过 ...

  2. MySQL的安装及使用教程

    MySQL的安装及使用教程 一.  MySQL的下载及安装 首先登陆MySQL的官网,选择Downloads→Windows→MySQL Installer→Windows(x86,32-bit),M ...

  3. 常用MVC框架

    J2EE开常用的SSH或SSI框架,对应解决表示层.业务逻辑层.持久化层的问题,其中对表示层的解决方案最多,常见的有Struts1/2,Spring MVC等,实际上都是在最底层的Servlet规范中 ...

  4. spring mvc controller间跳转 重定向 传参(转)

    spring mvc controller间跳转 重定向 传参 url:http://zghbwjl.blog.163.com/blog/static/12033667220137795252845/ ...

  5. 服务器负载均衡lvs(Linux Virtual Server)

    服务器负载均衡lvs(Linux Virtual Server) 一.总结 LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统. 三.Linu ...

  6. 【2037】利用字符串处理,输出x+y的结果

    Time Limit: 1 second Memory Limit: 50 MB [问题描述] 输入两个整数x,y输出它们的和.(0<=x,y<=10的100次幂) [输入] 共2行:   ...

  7. 【37.38%】【codeforces 722C】Destroying Array

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  8. Synopsys工艺库札记

    Synopsys工艺库札记 库的基本信息 库类 库类语句指定库名. library ( smic13HT_ss ) { ... <lirary description> ... } /*e ...

  9. [Node.js] Pass command line arguments to node.js

    Command line arguments are often used to modify the behavior of an application or specify needed par ...

  10. 用SQL找出前N名

    业务系统中常常会有排名的需求,考试和比赛中则更普遍了.Excel 中也有个 Rank 函数供排名之用,数据库中更不例外了. 如果须要找出工资最高的前三个员工工资(及其员工号). 只是."前三 ...