字符串与 Pascal 中的大量(数组)字符有何不同?
Posted
技术标签:
【中文标题】字符串与 Pascal 中的大量(数组)字符有何不同?【英文标题】:How strings differ from massive(array) of chars in Pascal? 【发布时间】:2022-01-24 05:34:12 【问题描述】:我有问题。为什么我不能将字符串的值分配给字符串,但使用字符它可以工作。为什么^^^^^^?字符串在哪里?为什么会有 a[i]? 是因为字符串和字符的内部表示吗?
program massive.pas;
type
chars = array [1..255] of char;
var
s,s1: string;
ch1,ch2: chars;
i: integer;
begin
s1 := '';
s := 'abrakadabra';
for i := 1 to 5 do
begin
s1[i] := s[i];
writeln(s1[i],#10,'^^^',s1,'^^^')
end;
ch2 := '';
ch1 := 'abrakadabra';
for i := 1 to 5 do
begin
ch2[i] := ch1[i]
writeln(ch2[i])
end;
writeln('%%%',ch2,'%%%');
for i := 1 to 5 do
writeln('&&&',s1[i],'&&&');
end.
*输出
a
^^^^^^
b
^^^^^^
r
^^^^^^
a
^^^^^^
k
^^^^^^
a
b
r
a
k
%%%abrak%%%
&&&a&&&
&&&b&&&
&&&r&&&
&&&a&&&
&&&k&&&
【问题讨论】:
您使用的数据类型string
没有标准化。您可能想指出您正在使用哪个编译器。你能告诉我们你想做什么,你首先写了什么代码吗?如果你想为array[1..255] of char
分配一个值到,你需要提供一个“赋值兼容”的值。对于数组,这意味着 恰好 255 个char
值的序列。但是,反过来通常也可以,因为有各种(非标准)算法可以容纳太多(或太少)char
值,例如默默地剪裁/丢弃(或在末尾插入空格)。
【参考方案1】:
type chars = Array[1..255] of Char
和String
的主要区别在于chars
数组具有固定长度,而字符串具有动态长度。
您没有说您使用哪个编译器,但我确实认为 String
类型在某些 Pascal 版本中被称为 ShortString
,最大长度为 255 个字符。 255 个字符的空间是预先分配的,结构包括一个长度字段,用于跟踪字符串的分配长度。
在您的示例中,您分配s1 := '';
,换句话说,长度设置为零。那么你在分配s1[i] := s[i];
时在for loop
中犯了一个错误没有设置s1的长度。
s1
的后续读取总是返回一个空字符串,因为长度字段为 0。
如果您要将字符分配给字符串,例如如:
for i := 1 to 5 do
begin
SetLength(s1, Length(s1)+1);
s1[i] := s[i];
writeln(s1[i],#10,'^^^',s1,'^^^');
end;
那么结果将是您最初所期望的。
最好将长度设置为for loop
之前的最后5个。
当然还有其他解决方案。一种是根本不设置长度,而是将循环中的字符串串联起来,让它自己处理长度字段:
for i := 1 to 5 do
begin
s1 := s1 + s[i];
writeln(s1[i],#10,'^^^',s1,'^^^');
end;
编辑 24.12.2021:
在你说的评论中:但我还是不明白,为什么,当我在 for 循环中写 s1[1] 时,一切正常?
...并且大概在end.
之前参考了这段代码:
for i := 1 to 5 do
writeln('&&&',s1[i],'&&&');
我们需要查看内存布局,知道分配给s1
的内存的第一个字节是字符串的长度。可以参考s[0]
。后续字节包含组成存储字符串的字符,它们可以称为 s[1]..s[n]。
当你写的时候(一开始)第一个字节被设置为0:
s1 := '';
// memory content:
0
|_|_|_|_|_|_|_|_|_| ...
然后你在第一个for
循环中写入时,通过直接操作内存将字符添加到s1
:
s1[i] := s[i];
// content after 5 characters
0 a b r a k
|_|_|_|_|_|_|_|_|_| ...
因为您没有使用连接(或在添加字符时调整长度),所以长度仍为 0。
然后在最后一个循环的最后,你通过直接访问内存再次获取字符,并得到你所做的结果,看似正确,但严重误用了字符串结构。
【讨论】:
但我还是不明白,为什么,当我在for循环中写s1[1]时,一切都奏效了? 你的问题和你在s1
上的操作方式有关,所以重点说一下。 s1
使用的内存大小为 256 字节,由于它是全局变量,因此在程序执行期间永远不会被释放。否则你的评论是正确的,但只是重新表述:内容的解释取决于长度字节,s [0]。如果为 0,则字符串被认为是空的(不管其他字节包含什么)。如果 s[0] 的值是 1 .. 255,那么从 s[1] 向前考虑那么多字符。以上是关于字符串与 Pascal 中的大量(数组)字符有何不同?的主要内容,如果未能解决你的问题,请参考以下文章