参考ブログ:http://www.cnblogs.com/pchmonster/archive/2011/12/14/2287686.html
ここですべてのコードは、Delphi7のテストです。
Delphiでは4,5,6,7文字列の種類は次のとおりです。
-
短い文字列(短い文字列)
-
長い文字列(長い文字列)
-
ワイド文字列(ワイド文字列)
-
ゼロで終わる文字列(ヌルで終了する文字列)、PChar型と文字の配列
1、短い文字列(短い文字列)
0番目の要素は、文字列の短い長さを含んでいるのでも短い文字列の長さと呼ばれる固定長さは、文字の最大数は255であり、(、(長さバイト)の文字列をバイト列列文字の数)。次のようにこのように256バイトのデフォルトの最大長さShortStringの(長さバイト255文字+ 1 = 256)、短い文字列は、二つの方法で宣言されました。
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
;
|
[0]は、文字列Sの長さの上記の例は、もちろん、短い文字列Sでlength関数の長さを決定するために使用され、得られます
文字は、特定の用途を参照して、ノートと、配列インデックスによってShortStringは、次の例を特定の場所にアクセスすることができます。
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、長い文字列(長い文字列)
長い文字列(AnsiStringの)は、動的文字列のみ使用可能なメモリによって制限されたサイズが割り当てられています。長い文字列を宣言し、ちょうどキーワード文字列を使用し、小さなパラメータが増加しないことができます。
デルファイ7 AnsiStringの文字は、単一バイトが格納されているに含まれています。
1
2
|
var
S:
string
;
|
それが動的に割り当てられるので、文字列を変更すること自由に一度、他への影響を心配することなく、クロスボーダーの問題を心配しないでください。列要素型はString型0の要素にアクセスしようとする試みは、コンパイルエラーが生成され、0ではありません。
長関数は、文字列の長さによって得ることができ、プロセスはまたはsetLength、長い文字列の長さを配置することができます。次のようにメモリにパーティション:
注フー文字列が長すぎる場合、String型の割り当てを与えられたとき、エラーの可能性がありますことを、「文字列リテラルは、最大で255個の要素を有していてもよいです」。あなたが疑問に思うこの時間は:制限はそれの文字文字列の数が存在しないと言うことではないでしょうか?
この問題のために、我々はコードサンプルを与える(プログラム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
.
|
ストリング255よりも長さも大きいが直接言及エラー上記文字列型の変数に割り当てられているこの時間は、報告されます。代替的には、割り当てによって割り当て+で使用される場合、例を参照して複数の部分に長い文字列となる(手順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
.
|
今回はそれが成功をコンパイルすることができます
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
;
|
そのようなA含ま端ヌルのメモリ領域へのテキスト・ポインタは「これはテストです。」文字列領域。これは次のコードと同等です:
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チャー型アレイ
最後の文字列が代わりPChar型を用いることができ、以下のように、コードは次のとおりです。
慎重なクロスボーダー・アクセス・メモリで出演
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
;
|
結果は以下のことを示しています。
最初の浅い上の文字列で私達は、後で理解では、このについて話しました。