我读过我不能真正在 pascal 中动态分配数组,但我也在考虑实现一个字符串结构。
在 C 中,我将通过创建一个
struct
来解决这个问题,其中包含一个指向字符数组(包含字符)的指针、一个长度整数和一个大小一。然后,当需要调整大小时,我会 malloc
char *
和 realloc
它。
typedef struct {
size_t size;
size_t length;
char* contents;
} String;
这可以在 (ISO) pascal 中完成吗?如果是这样,人们会怎样做呢?我不想使用内置的 pascal 动态数组,因为它有点违背了创建我自己的字符串类型的目的。
从评论来看,ISO pascal(标准的和扩展的)似乎不支持这样的东西。那么我该如何在 free pascal 中做到这一点呢?
在 Free Pascal 中,它可以类似于前面提到的 C 方法来实现:
type
TMyString = record
size: SizeUInt;
length: SizeUInt;
contents: PAnsiChar;
end;
...
procedure AllocMyString(var S: TMyString; L: SizeUInt);
begin
S.size := 0;
S.length := L;
GetMem(Pointer(S.contents), L);
end;
procedure ReallocMyString(var S: TMyString; L: SizeUInt);
begin
S.size := 0;
S.length := L;
ReAllocMem(Pointer(S.contents), L);
end;
我可以在 Pascal 中定义自己的字符串类型吗?
您需要观察字符串数据类型的以下特征: ISO 标准 7185 和 10206 定义的 Pascal † a 字符串数据类型 is a
packed
array of
char
integer
索引 1
开始,并且 integer
的 1
指数结束。例如
packed array[1..2] of char
是字符串数据类型。
如果目标是 write
文件,则可以将此类字符串变量传递给内置过程 writeLn
和 text
;如果源是 read
,则还可以将此类字符串变量传递给 readLn
和
text
in
扩展 Pascal文件。
我读过我无法真正在 Pascal 中动态分配数组 [...]
是/否:
对于 ISO 标准 7185 定义的标准 Pascal,这种说法在实践中是正确的,在理论上(通常)是错误的。 根据实现的不同,您可以动态分配不同数量的内存,但开销是非常不切实际的:
program variableLengthStringDemo(output);
const
stringMaximumLength = 4;
type
integerNonNegative = 1..maxInt;
stringLength = 0..stringMaximumLength;
stringCapacity = 1..stringMaximumLength;
string = record
length: stringLength;
case capacity: stringCapacity of
1: (character: packed array[1..1] of char);
2: (characterPair: packed array[1..2] of char);
3: (characterTriplet: packed array[1..3] of char);
4: (characterQuadruplet: packed array[1..4] of char);
end;
var
word: ^string;
begin
new(word, 3);
word^.characterTriplet := 'ABC';
word^.length := 3;
writeLn(word^.characterTriplet)
end.
对于已识别的
record
变量(identified 在 ISO 术语中本质上是指指针),内置过程 new
和 dispose
接受更多参数来选择特定变体。
这允许处理器的实现者“仅分配所需的内存”,但标准并未强制要求这样做。
然而,强制规定的是这样的变量不能再改变变体。
在上面的代码中,word^.capacity
被锁定到
3
。此外,由于所有 record
变体中的标识符必须是唯一的,因此您也必须在代码中处理多个标识符。 这使得使用这种方法处理字符串来达到生产目的几乎毫无用处。 您不能每次在代码中进行分支只是为了为当前活动的变体选择正确的标识符。 这太疯狂了。
,这种说法是完全错误的。
EP 定义了模式数据类型的概念。
模式数据类型表示“一组”数据类型。
你需要区分这个集合,从包里“选择”一个数据类型,来使用它。
判别式也可以提供给 new
和 dispose
。
program variableLengthArrayDemo(output);
type
characterSequence(capacity: integer)
= packed array[1..capacity] of char;
var
cheerfulMessage: ^characterSequence;
begin
new(cheerfulMessage, 12);
cheerfulMessage^ := 'Hello world!';
writeLn(cheerfulMessage^)
end.
EP中还有其他实现变长数组的方法,这只是其中一种。
注意: 在 EP 和 SP 中,如果您
dispose
dispose
需要与相应的
new
完全相同的参数。
new(variable, 3)
→ dispose(variable, 3)
。†: 实际上,有固定字符串类型
(这里介绍),可变字符串类型(EP的string
模式)和规范字符串类型(纯粹用于定义目的的元数据类型),统称为
字符串类型. [...] 那么我该如何在 Free Pascal 中做到这一点?
在 FreePascal 中