level 1
黄金止手
楼主
静态数组
下标可以是顺序类型(整数、字符、枚举、Boolean)或其子域,但不能是ByteBool系列。
下标的序数(对于整数是其值,对于其他类型是ord()的值)必须在 SizeInt 的范围内。数组整体大小也必须在 SizeInt 范围内。
即 32 位程序的数组下标必须在序数值 -2147483648..2147483647 内,数组整体大小必须在 0..2147483647 内。
array [0..MaxLongInt] of Char 或 array [2..$80000000] of Char 无法通过编译,而 array [0..MaxLongInt-1] of Char 可以。
但实际上 Windows 10 下 32 位 FP 程序基本无法分配大于 1.9GB 的空间,所以平台限制比语法限制更苛刻。
静态数组可以直接用赋值来复制,赋值后仍是两个数组。
动态数组
长度必须是非负数,且在 SizeInt 的范围内。在 setlength 里令长度为 LongInt 范围内的负数不会产生编译错误,但会产生运行错误。
同样的,实际上在具体系统中很可能不能分配到这个长度。
动态数组下标必须是整数,且从 0 开始到长度减一。
简单地使用 DynArrA:=DynArrB 会令 DynArrA 和 DynArrB 成为同一数组的两个引用。故而需要用 Copy 来复制数组。
动态数组形式上可以是多维的,但多维动态数组内存空间并不一定连续分配,不像多维静态数组一样是个整体。多维动态数组更像是一维动态数组的迭代。
无论是静态数组还是动态数组,传入方法(过程/函数)时参数都不能写成匿名类型(即 array [TIndex] of Atype / array of Atype 形式),必须给数组类型一个类型标识符,方可将其照原样传入方法。
开放数组
开放数组不是真正的变量类型,只是一种只出现于参数列表中的“伪”类型。
声明形式是参数列表中写 array of AType,可以加 const/var/out 修饰符。
开放数组只能是一维的,而且在方法内部是静态的,不可改变长度。但在调用方法时,可以传入不同长度的静态或动态数组,还可以用 A[left..right] 的形式传入数组的一部分。
在方法内部,开放数组的下标是从 0 开始到长度减一的整数。可以通过 high(A) 获得开放数组下标的最大值。
调用方法时,一个开放数组参数实际上是两个参数:数组首地址和数组最大下标(即长度减一)。和直接这么写的区别是开放数组参数可以做范围检查,安全性更好。
开放数组参数若要传递,只能传给另一个开放数组参数。
参数列表中的修饰符对数组的影响
Pascal 有 var/const/out/constref 四种参数修饰和无修饰参数。
constref 在 FP 的 2.6.1 版本后才得到支持。
out 仅在 FP 的 ObjFPC 和 Delphi 模式下得到支持。
无修饰表示传值,等于有一个隐含的 形参:=实参 赋值语句。
对于静态数组和开放数组,无修饰参数会导致在栈上把数组复制一遍。对于动态数组则是进入方法时引用数加一,离开时引用数减一。
var, out, constref 修饰表示传递引用,var 表示该参数可变,out表示该参数可变且传入值无意义,constref 表示该参数被视作不可变的常量。
out 和 var 的实际区别在修饰动态数组和动态字符串之时。var 和 constref 修饰的动态类型引用数不会自动改变,但 out 所修饰者在进入方法时引用数减一或被清空。
const 表示传递的参数被视作常量,但究竟是传值还是传引用是编译器决定的。对于开放数组和动态数组,const 等价于 constref 。
部分很短的静态数组用 const 修饰可能会发生按值传递(即发生复制)。
考虑到目前 FP 在传值参数中都把数组复制到栈上,对于静态数组和开放数组参数,最好加 var/const 修饰。数组参数能加 const 就加 const,需要修改时加 var ,实在不行时(如外部不能改变,但内部又要修改时)才写无修饰参数。
2016年08月24日 10点08分
1
下标可以是顺序类型(整数、字符、枚举、Boolean)或其子域,但不能是ByteBool系列。
下标的序数(对于整数是其值,对于其他类型是ord()的值)必须在 SizeInt 的范围内。数组整体大小也必须在 SizeInt 范围内。
即 32 位程序的数组下标必须在序数值 -2147483648..2147483647 内,数组整体大小必须在 0..2147483647 内。
array [0..MaxLongInt] of Char 或 array [2..$80000000] of Char 无法通过编译,而 array [0..MaxLongInt-1] of Char 可以。
但实际上 Windows 10 下 32 位 FP 程序基本无法分配大于 1.9GB 的空间,所以平台限制比语法限制更苛刻。
静态数组可以直接用赋值来复制,赋值后仍是两个数组。
动态数组
长度必须是非负数,且在 SizeInt 的范围内。在 setlength 里令长度为 LongInt 范围内的负数不会产生编译错误,但会产生运行错误。
同样的,实际上在具体系统中很可能不能分配到这个长度。
动态数组下标必须是整数,且从 0 开始到长度减一。
简单地使用 DynArrA:=DynArrB 会令 DynArrA 和 DynArrB 成为同一数组的两个引用。故而需要用 Copy 来复制数组。
动态数组形式上可以是多维的,但多维动态数组内存空间并不一定连续分配,不像多维静态数组一样是个整体。多维动态数组更像是一维动态数组的迭代。
无论是静态数组还是动态数组,传入方法(过程/函数)时参数都不能写成匿名类型(即 array [TIndex] of Atype / array of Atype 形式),必须给数组类型一个类型标识符,方可将其照原样传入方法。
开放数组
开放数组不是真正的变量类型,只是一种只出现于参数列表中的“伪”类型。
声明形式是参数列表中写 array of AType,可以加 const/var/out 修饰符。
开放数组只能是一维的,而且在方法内部是静态的,不可改变长度。但在调用方法时,可以传入不同长度的静态或动态数组,还可以用 A[left..right] 的形式传入数组的一部分。
在方法内部,开放数组的下标是从 0 开始到长度减一的整数。可以通过 high(A) 获得开放数组下标的最大值。
调用方法时,一个开放数组参数实际上是两个参数:数组首地址和数组最大下标(即长度减一)。和直接这么写的区别是开放数组参数可以做范围检查,安全性更好。
开放数组参数若要传递,只能传给另一个开放数组参数。
参数列表中的修饰符对数组的影响
Pascal 有 var/const/out/constref 四种参数修饰和无修饰参数。
constref 在 FP 的 2.6.1 版本后才得到支持。
out 仅在 FP 的 ObjFPC 和 Delphi 模式下得到支持。
无修饰表示传值,等于有一个隐含的 形参:=实参 赋值语句。
对于静态数组和开放数组,无修饰参数会导致在栈上把数组复制一遍。对于动态数组则是进入方法时引用数加一,离开时引用数减一。
var, out, constref 修饰表示传递引用,var 表示该参数可变,out表示该参数可变且传入值无意义,constref 表示该参数被视作不可变的常量。
out 和 var 的实际区别在修饰动态数组和动态字符串之时。var 和 constref 修饰的动态类型引用数不会自动改变,但 out 所修饰者在进入方法时引用数减一或被清空。
const 表示传递的参数被视作常量,但究竟是传值还是传引用是编译器决定的。对于开放数组和动态数组,const 等价于 constref 。
部分很短的静态数组用 const 修饰可能会发生按值传递(即发生复制)。
考虑到目前 FP 在传值参数中都把数组复制到栈上,对于静态数组和开放数组参数,最好加 var/const 修饰。数组参数能加 const 就加 const,需要修改时加 var ,实在不行时(如外部不能改变,但内部又要修改时)才写无修饰参数。