문자열, 문자열, PChar는, char 배열의 다양한 델파이

참고 블로그 : http://www.cnblogs.com/pchmonster/archive/2011/12/14/2287686.html

 

상기 모든 코드는 Delphi7 테스트에 있습니다.

델파이에서 4,5,6,7 문자열 유형은 다음과 같습니다

  • 짧은 문자열 (짧은 문자열)
  • 긴 문자열 (긴 문자열)
  • 와이드 문자열 (와이드 문자열)
  • 제로 끝나는 문자열 (문자열을 null로 끝나는) 문자, PChar는 어레이

1, 짧은 문자열 (짧은 문자열)

0 번째 요소는 문자열의 짧은 길이를 포함하고 있기 때문에 고정 길이, 최대 문자 수는 짧은 문자열 길이라고 255이며,이 (길이 바이트) 문자열을 바이트 (문자열 문자열 문자 수). 다음 따라서 256 바이트의 기본 최대 길이이다 ShortString은 (길이가 255 개 바이트 문자 + 1 = 256), 짧은 문자열은 두 가지 방법으로 선언

1
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 ;

  

[0] 문자열 S의 길이가 상기의 예는 물론, 짧은 문자열 S.하여 길이 함수의 길이를 결정하기 위해 사용될 수를 얻을 수있다

문자는 특정 사용을 참조하고, 참고로, 배열 인덱스에 의해 ShortString은 다음의 실시 예를 특정 위치를 액세스 할 수있다 :

1
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, 긴 문자열 (긴 문자열)

긴 문자열 (를 AnsiString)는 사용 가능한 메모리에 의해 제한되는 크기의 동적 문자열을 할당한다. 단지 문자열 키워드 사용, 긴 문자열을 선언 작은 매개 변수가 증가하지 않는 될 수 있습니다.

단일 바이트에 포함 된 델파이 7 AnsiString과 문자가 저장됩니다.

1
var
   S:  string ;

  

이 동적으로 할당되기 때문에, 다른에 미치는 영향에 대한 걱정없이 문자열을 수정할 무료, 일단 국경 문제에 대한 걱정을하지 않습니다. 문자열 요소 유형은 컴파일 오류가 발생합니다 String 형 0의 요소에 액세스 할 수 없습니다 0, 시도이다.

길이 함수는 문자열의 길이에 의해 얻을 수 있고, 프로세스는 SetLength를 긴 스트링 길이를 배치 할 수있다. 다음과 같이 메모리에 분할 :

0,013

 

  참고 푸 문자열이 너무 긴 경우 문자열 유형 할당을 주어 졌을 때, 오류가있을 수 있음 : "문자열 리터럴은 최대 255 개 개의 요소를 가질 수 있습니다." 당신이 궁금해이 시간 : 제한이 문자 문자열의 수가없는 말은 아니다?

  이 문제에 대한, 우리는 코드 예제를 제공 ( 프로그램 1 )

1
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 .

  한 오류가보고 될 현제 시간, 스트링 (255)보다 더 큰 길이를 직접 입력 문자열의 변수에 할당된다. 다른 방법은, 할당에 의해 할당 + 사용될 때, 예를 참조 여러 부분으로 긴 문자열로한다 ( 절차 2 )

1
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 .

  이번에는 성공을 컴파일 할 수 있습니다

3 넓은 문자열 (와이드 문자열)

넓고 문자열로 긴 문자열 만 사용할 수있는 메모리의 크기 및 동적 할당의 구현에 의해 제한.

在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 ;

  

등의 메모리 영역에 텍스트 포인터 포인트는 최종 널 포함 '이 테스트입니다.'문자열 영역을. 어느 다음 코드와 동일합니다 :

1
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 차르 형 어레이

다음과 같이 마지막 문자 배열이 대신 PChar는 사용할 수 있습니다, 코드는 다음과 같습니다

주의 국경 액세스 메모리의 겉 모습

1
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 ;

  

결과는 다음을 보여준다 :

0,014   0,015

최초의 얕은에 문자열에 우리는 나중에 이해에서 이것에 대해 이야기했다.

추천

출처www.cnblogs.com/jijm123/p/12285891.html