Delphi in a variety of string, String, PChar, Char array

Reference blog: http://www.cnblogs.com/pchmonster/archive/2011/12/14/2287686.html

 

Wherein all of the code are at Delphi7 test.

In Delphi 4,5,6,7 character string types include:

  • Short string (Short String)
  • Long strings (Long String)
  • Wide string (Wide String)
  • Zero-terminated string (Null-Terminated String), PChar and array of characters

1, short string (Short String)

Fixed length, the maximum number of characters is 255, also referred to a short string length bytes (Length-byte) string, because the 0-th element contains the short length of the string (string string the number of characters). Thus ShortString default maximum length is 256 bytes (255 characters in length byte + 1 = 256), a short string declared in two ways, as follows:

1
2
3
4
5
6
7
8
9
var
   S:  ShortString ;    { 255个字符长度,256个字节}
   S1:  String [ 255 ];   { S1和S的字符类型一样,通过使用String声明字符串并且在String后面用中括号规定字符个数的形式定义字符串}
   Len:  Integer ;
begin
   S :=  'Hello' ;
   Len := Ord(S[ 0 ]);  { Len现在包含S的长度为5,Ord函数可以把一个字符类型转换为整数类型}
   Len := SizeOf(S);  { Len现在包含的是ShortString类型的大小,为256字节,并不是字符串的长度}
end ;

  

Examples of the above [0] of the length of the string S can be obtained, of course, also be used to determine the length of the Length function by a short string S.

Characters can access a particular location in ShortString by the array index, the following examples with reference to the specific use, and notes:

1
2
3
4
5
6
7
8
9
10
11
12
var
   S:  string [ 8 ]; {这种定义方式,是定义S是一个字符串,且S是最多含有8个字符的字符串}
   i:  Integer ;
begin
   S :=  'a_pretty_darn_long_string' ;
   { 因为S只有8个字符大小,
   因此s的实际存储的内容为“a_pretty”}
   i :=  10 ;
   S[i] :=  's' ;
   { 因为S只有8个字符大小,
   试图改写第10个元素,将会使内存混乱}
end ;

  

2, long strings (Long String)

Long string (the AnsiString) is assigned a dynamic string, the size of which is limited only by available memory. Declare a long string, just use the keyword String does not increase the small parameter can be.

Delphi 7 AnsiString characters contained in a single byte is stored.

1
2
var
   S:  string ;

  

Because it is dynamically allocated, once free to modify the string, without worrying about the impact on the other, do not worry about cross-border issues. String element type is not 0, attempts to access the elements of type String 0 will produce a compilation error.

Length function can be obtained by the length of the string, the process can also SetLength long string length disposed. Partitioned in memory as follows:

0013

 

  Note that when given a String type assignment when Fu string is too long, may be error: "String literals may have at most 255 elements". This time you wonder: is not to say there is no limit the number of characters String of it?

  For this problem, we give a code sample ( program 1 )

1
2
3
4
5
6
var
     s:  string ;
begin
     s:=  '<?xml version="1.0" encoding="UTF-8"?><Msg><AppHdr><CharSet>UTF-8</CharSet><Fr>000100</Fr><To>SDC</To><BizMsgIdr>0000000002</BizMsgIdr><MsgDefIdr>V1.0</MsgDefIdr><BizSvc>067</BizSvc><CreDt>20130227100434</CreDt><Sgntr>fb3LY5VmhonZwhP+ntxI9A==</Sgntr></AppHdr><Document><Data><FndNm>name</FndNm><TtlFndVol>12681656.00</TtlFndVol><FndCd>159999</FndCd><FndSts>0</FndSts><NAV>1.0251</NAV><NtValDt>20130301</NtValDt><NtValTp>0</NtValTp></Data></Document></Msg>' ;
     
end .

  This time, a length greater than the string 255 is directly assigned to a variable of type string above mentioned error will be reported. The alternative is to be a long string into multiple parts, when used in an assignment + by assignment, see example ( Procedure 2 )

1
2
3
4
5
6
7
8
9
10
var
     s:  string ;
begin
     s:=  '<?xml version="1.0" encoding="UTF-8"?><Msg><AppHdr><CharSet>UTF-8</CharSet><Fr>000100</Fr><To>SDC</To>'
     '<BizMsgIdr>0000000002</BizMsgIdr><MsgDefIdr>V1.0</MsgDefIdr><BizSvc>067</BizSvc><CreDt>20130227100434</CreDt>'
     '<Sgntr>fb3LY5VmhonZwhP+ntxI9A==</Sgntr></AppHdr><Document><Data><FndNm>FundName</FndNm><TtlFndVol>12681656.00</TtlFndVol>'
     '<FndCd>159999</FndCd><FndSts>0</FndSts><NAV>1.0251</NAV><NtValDt>20130301</NtValDt><NtValTp>0</NtValTp></Data>'
     '</Document></Msg>' ;
 
end .

  This time it can compile a success

3, wide string (Wide String)

Wide and long string as a string, restricted only by the size of available memory, and the implementation of dynamic allocation.

在Delphi 7 中WideString被实现为2个字节存储一个字符,用WideString来处理多字节字符(比如汉字)是十分方便的。如:

1
2
3
4
5
6
7
8
9
10
var
   S:  string ;
   { 在Delphi 7中默认string等同于AnsiString}
   WS:  WideString ;
begin
   S :=  '世界你好' ;
   WS := S;
   ShowMessage(S[ 1 ]);   { 此时无任何显示,因为S[1]取出的是‘世’的一半}
   ShowMessage(WS[ 1 ]);  { 显示‘世’}
end ;

  要理解宽字符串就必须理解字符编码的规则,比如ASCII、UTF-8……

 

4、零结尾字符串(Null-Terminated String)、PChar和字符数组

在C和C++中没有真正的字符串数据类型,都是通过以Null结尾(0)的字符数组来实现的,字符数组没有长度字节,因此只能通过结尾的Null标志来作为字符串的字符结束标志。又因为Windows是用C编写的,很多Windows函数要用到以字符数组作为参数,但Pascal字符串类型不是字符数组,因为为了让Pascal字符串也能与Windows兼容,就需要一个字符串数组,PChar类型正是符合这种需求,在任何需要字符数组的地方都可用PChar。

虽然AnsiString和WideString都已经实现了NULL

相应的也有PAnsiChar和PWideChar,分别对应于AnsiChar字符和WideChar字符。

例如:Windows MessageBox函数,此函数声明如下:

1
function  MessageBox(hWnd: HWND; lpText, lpCaption:  PChar ; uType: UINT):  Integer ; stdcall;

  

第二个和第三个参数需要一个指向字符数组的指针,为了可以调用此函数,有以下三种方法来实现

1、PChar()类型转换

1
2
3
4
5
6
7
8
9
var
   Text:  string ;
   Caption:  string ;
begin
   Text :=  'This is a test.' ;
   Caption :=  'Test Message' ;
   MessageBox( 0 PChar (Text),  PChar (Caption),  0 );
   { 这里PChar用来把string类型转换为Null结尾的字符串}
end ;

 其中

2、PChar变量

我们先做一个实现,看看PChar类型到底是啥呢?

运行下面程序:

1
2
3
4
5
6
7
8
9
var
   Text:  PChar ;     { 声明为PChar类型}
   Str:  string ;     { 声明为String类型}
begin
   Text :=  'This is a test.' ;              { 都被赋予了相同的字符串}
   Str :=  'This is a test.' ;
   ShowMessage(IntToStr(SizeOf(Text)));    { 4字节,实质是指针}
   ShowMessage(IntToStr(SizeOf(Str)));     { 也是4字节,也是指针}
end ;

  

通过上面的程序,我们知道Text(PChar类型)只不过是一个指针而已。

1
2
3
4
5
6
7
var
   Text:  PChar ;
begin
   Text :=  'This is a test.' ;
   MessageBox( 0 , Text,  'Test Message' 0 );
   { 这里Text直接声明为了PChar类型,字符串常量可以直接用}
end ;

  

Text pointer points to a memory area of ​​such a contained end Null 'This is a test.' Character string region. Which is equivalent to the following code:

1
2
3
4
5
6
7
8
9
10
const
   TempString:  array [ 0..15 of  Char  'This is a test.' # 0 ;
var
   Text:  PChar ;
begin
   Text := @TempString[ 0 ];
   {Text指向Null结尾的TempString字符数组的第0个元素的地址,
   也就是整个字符数组的首地址}
   MessageBox( 0 , Text,  'Test Message' 0 );
end ;

  

3, Char type array of characters

Last Char array can also be used instead of PChar, code is as follows:

Appearances in careful cross-border access memory

1
2
3
4
5
6
7
8
9
10
11
12
var
   Text1:  array [ 0..14 of  Char ;   { 大小为15个字符}
   Text2:  array [ 0..20 of  Char ;   { 大小为21个字符}
begin
   Text1 :=  'This is a test.' ;    {Text1和Text2的字符长度都为15个字符}
   Text2 :=  'This is a test.' ;
   MessageBox( 0 , Text1,  'Test Message 1' 0 );
   {因为Text1的字符长度超过了其声明的大小,因为会内存访问混乱,显示换乱}
  
   MessageBox( 0 , Text2,  'Test Message 2' 0 );
   {Text2的字符长度比起声明的大小要小,因为正常访问,显示正确}
end ;

  

The results show the following:

0014   0015

On the string on the first shallow we talked about this at a later time understanding.

Guess you like

Origin www.cnblogs.com/jijm123/p/12285891.html