Delphi数组
参考:http://www.cnblogs.com/huangjacky/archive/2009/12/21/1628833.html
数组就是一堆相同特性数据的一个组合,也就是每个元素的类型必须是一样的,当然在其他一些弱语法的语言里面,数组的元素可以是千奇百怪,例子
var
A : Array[0..2] of Integer;
begin
A[0] := 1;
a[1] := 1.0; //这里是错的,因为每个元素都必须是Integer类型
end;
Delphi中数组的分类
1.定长和不定长
定长数组
定长数组也就是长度在声明的时候就确定的,后面是不能改变的,而在定长数组里,起始序号不必从0开始,可以自己定,例如
var
A : Array[2..3] of Integer;
begin
A[2] := 1;
SetLength(A,3); //这里会出错,因为定长数组不能再分配
end;
从上面我们可以看到起始序号是2,但是步长是1,是不能改变的。为什么我们看到很多数组的起始序号是0呢?习惯而已。
来看一个特殊用法
type
THuangJacky = (hjA, hjB, hjC);
const
//用法1
B : Array[0..2] of string = ('A', 'B', 'C');
//用法2
C : Array[THuangJacky] of string('A', 'B', 'C');
var
H : THuangJacky;
S :String;
begin
S := B[Ord(H)]);
S := C[H];
//B[H]和C[1]都会出错
end;
从上面的例子可以看出只要是有序数类型都可以当做数组的序号,但是我们用的时候序号就必须是声明的哪种序数类型,所以上面的代码注释中才会写出两种错误的情况
不定长数组
不定长数组:动态数组,也就是声明的时候没有说长度是多少,在使用之前必须声明,长度是可以再分配的,序号必须从0开始,例子
var
A : Array of Integer; //定长数组可能的定义是 A :Array[0..10] of Integer
begin
SetLength(A, 3); //数组一共有3个元素
A[0] := 1;
A[1] := 2;
A[2] := 3;
//A[3]没有,因为只有3个元素 SetLength(A, 4); //如果变长长度,直接增加后面的元素
A[3] := 4; //现在增加了第四个元素,而前三个元素还是那三个 SetLength(A, 3); //如果长度变短了,超出部分就会被去掉
//现在A[3]没有了
end;
有时候,大家这样要先设定长度,在赋值,很麻烦,现在介绍一个一气呵成的招数
type
TA = Array of Integer;
var
A : TA;
begin
A := TA.Create(1, 2, 3);
//此招请勿在Delphi 7上面使用 //使用上面的方法之后,A[0] :=1, A[1] := 2, A[2]:=3
end;
2.一维和多维
前面的所有例子,所讨论的都是一维数组,要想弄一个矩阵(多维数组)怎么办?
var
A : Array[0..2, 0..2] of Integer;
B : Array[0..2] of Array[0..2] of Integer;
begin
A[0, 0] := 1;
B[0, 0] := 1;
end;
两种方法都是可以的,下面介绍二维数组中的不定长数组
var
B : Array of Array of Integer
begin
//设置一个3*3的矩阵
SetLength(B, 3, 3); //如果需要实现齿状数组,必须像下面这么做
SetLength(B, 3);
SetLength(B[0], 1);
SetLength(B[1], 2);
SetLength(B[2], 3);
end;
接下来介绍几个关于数组的常用函数
1.复制函数
var
A, B : Array[0..1] of Integer;
begin
A[0] := 1;
A[1] := 2;
B := A;
B[0] :=2;
ShowMessageFmt('A0:%D, B0:%D', [A[0], B[0]]); //A0:1,B0:2
end;
这个效果就是我们想要的,貌似没有什么好说的,但是如果是动态数组呢?
var
A, B : Array of Integer;
begin
SetLength(A, 2);
SetLength(B, 2);
A[0] := 1;
A[1] := 2;
B := A;
B[0] := 2;
ShowMessageFmt('A0:%D, B0:%D', [A[0], B[0]]); //A0:2, B0:2
//很显然改了B[0]的值之后,对A[0]的也造成了影响,所以B和A之间存在着某种联系
end;
现在怎么办?A和B被关联到一个地址了,其实现在我们可以使用Copy函数,就可以解决这个问题了
var
A, B : Array of Integer;
begin
SetLength(A, 2);
SetLength(B, 2);
A[0] :=1;
A[1] :=2;
B := Copy(A); //整个数组都赋值过去
B := Copy(A, 0, 2); //选择性复制
B[0] := 2;
ShowMessageFmt('A0:%D,B0:%D', [A[0], B[0]]); // A0:1,B0:2
end;
2.序号相关
函数Low()和High()值得信赖,不过我们需要注意的是,他们返回的类型是我们数组的序号的那个类型,并不都是Integer,如前面例子中的THuangJacky
var
A : Array of array of string;
I, J : Integer;
begin
SetLength(A, 10);
for I := Low(A) to High(A) do
begin
SetLength(A[I], I);
for J := Low(A[I]) to High(A[I]) do
A[I, J] := IntToStr(I) + ',' + IntToStr(J) + ' ';
end
end;
end.
3.数组长度
Length()函数返回的是Integer类型
var
A : Array of Integer;
begin
SetLength(A, 2);
Length(A);
end.
从上面的那个复制的例子我们可以看出来:定长数组变量就是一个变量,所以可以直接用 := 来赋值,而动态数组变量就是一个指针,如果用了 :=来赋值,两个变量就关联在一起了
var
A :Array[0..2] of Integer;
B :Array of Integer;
begin
ShowMessageFmt('A:%8x, A[0]:%8p', [Integer(@A), @A[0]]); //一样,从地址来看这个数组控件在栈上面
SetLength(B, 3);
ShowMessageFmt('B:%8p, B[0]:%8p', [B, @B[0]]); //一样,这个数据空间在堆上面
end
我们看到A要取地址才和A[0]取地址一样,那么也就是说A就是A[0];
而B直接就和B[0]取地址一样了,也就是说B就是B[0]的地址
数组在内存中的分布:连续分布的,间隔就是每个元素的大小
var
A: Array[0..2] of Integer;
B: Array of Integer;
begin
A[1] := 123;
//从A也就是A[0]的地址上面往下走4个直接就是A[1]
ShowMessageFmt('A[1]:%D,直接取值:%D',[A[1], PInteger(Integer(@A)+4)^]);
//一样,都是123
SetLength(B, 3);
B[2] := 88;
//从B往下走8个字节就是B[2]
ShowMessageFmt('B[2]:%D,直接取值:%D',[B[2],PInteger(Integer(B)+8)^]);
end;
但是动态数组的结构和字符的结构就很像了
偏移 | -8 | -4 | 0~Length*元素 |
内容 | 32位引用次数 | 元素个数 | 实际内容 |
Delphi数组的更多相关文章
- delphi数组如何初始化
https://wenda.so.com/q/1535561587217078delphi数组如何初始化rosegirl09112级分类:其他被浏览44次2018.07.01检举满意答案 csx330 ...
- delphi 数组类型与数组指针的巧妙利用
{本例通过存取结构, 慢慢引入了数组类型与指针的一些使用方法; 其中六个小例子的测试内容和结果都是一样的. ---------------------------------------------- ...
- delphi 数组类型
数组类型 数组类型定义了一组指定类型的元素序列,在方括号中填入下标值就可访问数组中的元素.定义数组时,方括号也用来指定可能的下标值.例如,下面的代码中定义了一个有 24 个整数的数组:type ...
- delphi数组之菜鸟篇
数组是可以通过索引来引用的同类型数据的列表.按照存储空间的获取方式,Delphi支持的数组类型有两种,即静态数组和动态数组.所谓静态数组就是在声明时就已经确定大小的数组类型,而动态数组是指其大小在声明 ...
- delphi 数组的使用
delphi中数组就跟string使用类似,数组分为:动态数组和静态数组 还可根据数据的功能分为:数组(一维数组).二维数组.三维数组...静态数组: 固定长度,内容需要定义时添加.动态数组: 故名思 ...
- Delphi - 数组 详解
技术交流,DH讲解. 首先我们要知道什么是数组?数组是一堆相同特性数据的一个集合,也就是每个元素的类型必须是一样的,当然在其他一些弱语法的语言里面,数组的元素可以千奇百怪. 例子: ? 1 2 3 4 ...
- delphi数组作为参数传值
在函数中如果数组的个数不定,可以使用开放数组参数 实参可以接受静态数组和动态数组 procedure p1(a:array of Byte); begin ShowMessage( IntToHex( ...
- DELPHI数组,指针,字符串转换的例子
关于数组,指针,字符串转换的例子 var aa: array [0..5] of Char; bb:Pointer; cc:string; dd:PChar; procedure ...
- Delphi - 数组和结构体
技术交流,DH讲解. 记得很早之前我就说过,数组和结构体在内存中其实一样的,他们都是连续分布的.例如: ? 1 2 3 4 TMyStruct = record A,B,C:Integer; en ...
随机推荐
- 跟着百度学PHP[4]OOP面对对象编程-9-封装性,访问控制[private、pubic、protected]
其实之前就已经在封装的时候说到了.这个也属于封装的范畴吧. 用到的三个关键字(旁边是其中文翻译) private(私有的) public(公众的) protected(受保护的) 00X1 priva ...
- 子类重载父类的方法“parent::方法名”转于 恩聪PHP学习教程
在PHP中不能定义重名的函数,也包括不能再同一个类中定义重名的方法,所以也就没有方法重载.单在子类中可以定义和父类重名的方法,因为父类的方法已经在子类中存在,这样在子类中就可以把从父类中继承过来的方法 ...
- Python自动化之sqlalchemy关联查询
外键关联 from sqlalchemy import ForeignKey from sqlalchemy.orm import relationship class Address(Base): ...
- 详解 Too many open files
运行在Linux系统上的Java程序可能会出现"Too many open files"的异常情况,且常见于高并发访问文件系统,多线程网络连接等场景. 程序经常访问的文件.sock ...
- register_shutdown_function 函数详解
设定错误和异常处理三函数 register_shutdown_function(array(‘Debug’,'fatalError’)); //定义PHP程序执行完成后执行的函数 set_error_ ...
- 从其它系统登录到SharePoint 2010系统的单点登录
以前做的只是使用SharePoint的单一登录,用SharePoint去登录其他的系统,现在要反过来,用Form认证的系统来登录SharePoint. 我们都知道,SharePoint使用的是域认证系 ...
- C#之常见数组编码错误
摘抄自C#本质论(第四版,P55) 常见错误 错误描述 改正后的代码 int numbers[] 用于声明数组的方括号放在数据类型之后,而不是在变量标识符之后 int[] numbers; int[] ...
- oracle11g 连接问题
一.The Network Adapter could not establish the connection 状态: 失败 -测试失败: IO 错误: The Network Adapter c ...
- ios 转发一篇对于6 plus的分辨率模式的说明
http://segmentfault.com/q/1010000002545515 分为兼容模式和高分辨率模式. 兼容模式 当你的 app 没有提供 3x 的 LaunchImage 时,系统默认进 ...
- 如何让两个 并列的div高度相等
哪个div Height值大,就将其值赋给Height值小的div,从而使2个div高度始终保持一致. function $(id){ return document.getElementById(i ...