源码不长,只一个过程。如下:
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
OpenDialog1: TOpenDialog;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.DFM}procedure TForm1.Button1Click(Sender: TObject);
type
ByteRa = array[0..0] of byte;
Bytep0 = ^ByteRa;
var
F: file;
buff: Bytep0;
i, Fsz: integer;
begin
if OpenDialog1.Execute then begin
AssignFile(F, OpenDialog1.FileName);
Reset(F, 1);
Fsz := FileSize(F);
GetMem(buff, Fsz);
BlockRead(F, buff^, Fsz);
i := 900;
ShowMessage(IntToStr(buff[i]));
FreeMem(buff);
CloseFile(F);
end;
end;这段代码是我写的,可是我有几点不明白:
第一:位图应该是二进制的,可是buff却是一个指针数组,而且这个数组又是byte类型的,这样为什么可以???第二:buff应该是指向byte数组的第0个元素,而ByteRa = array[0..0] of byte;ByteRA只有一个元素呀,为什么i := 900;而这样buff[i]不会越界,而且有返回值,是211,一个整数。???很是奇怪,请大家指点一二。谢谢了。
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
OpenDialog1: TOpenDialog;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.DFM}procedure TForm1.Button1Click(Sender: TObject);
type
ByteRa = array[0..0] of byte;
Bytep0 = ^ByteRa;
var
F: file;
buff: Bytep0;
i, Fsz: integer;
begin
if OpenDialog1.Execute then begin
AssignFile(F, OpenDialog1.FileName);
Reset(F, 1);
Fsz := FileSize(F);
GetMem(buff, Fsz);
BlockRead(F, buff^, Fsz);
i := 900;
ShowMessage(IntToStr(buff[i]));
FreeMem(buff);
CloseFile(F);
end;
end;这段代码是我写的,可是我有几点不明白:
第一:位图应该是二进制的,可是buff却是一个指针数组,而且这个数组又是byte类型的,这样为什么可以???第二:buff应该是指向byte数组的第0个元素,而ByteRa = array[0..0] of byte;ByteRA只有一个元素呀,为什么i := 900;而这样buff[i]不会越界,而且有返回值,是211,一个整数。???很是奇怪,请大家指点一二。谢谢了。
2.象以下的type 声明
type
ByteRa = array[0..0] of byte;
不会分配内存,Array的大小是动态的,BlockRead(F, buff^, Fsz);语句后它的大小就是900了。Pascal语言里没有规定数组下标从零开始,可以从1,也可以从5、13或别的数开始。所以数组的首元素可以是array[0]或array[-9]或array[3]等。
我说得不好,你到Google上用"Dynamic array"搜索,有的外国网站说得比较透彻。
FreeMem(buff);
1.二进制与byte并不矛盾,那么你说i := 900;而这样buff[i],读出的值是211,那么是blockread自动将二进制转换为byte吗?这样理解对吗?2.type
ByteRa = array[0..0] of byte;
不会分配内存,我想应该是对的。那么ByteRa = array[0..0] of byte;是动态数组吗?它与ByteRa = array of byte;有什么区别呢?》》》》》Array的大小是动态的,BlockRead(F, buff^, Fsz);语句后它的大小就是900了。
应该不是900吧?应该是Fsz的大小吧?我只想把这个问题搞明白。谢谢了。
是这样....
BlockRead(F, buff^, Fsz);语句后它的大小就是900了。应该不是900吧?应该是Fsz的大小吧?我觉得如果是想看最后一个数据应该是FSZ吧,只要900不大于fsz这句话就没有问题,你可以取个大于fsz的数,看看会出现什么情况,我没有试,只是猜想。
另外,array [0..0] of byte;就是动态的。
那么怀array of byte有何区别。array of byte
必须用setlength来分配内存并设置娄组的长度,而array [0..0] of byte;
必须用GetMem来分配内存。(分配了内存,而又执行了blockread后,buff的长度是多少呀????)我这样理解对吗?
还有
我i := Fsz + 2000,这样都没有问题,程序不报错,有值显示,为0。真的奇怪,为什么呢?
如果再是很大的话,就报地址错了,
谢谢你详细的解释,呵呵。。
看来果然是BlockRead读的时候就转成了byte。另:
我不熟悉C++,一直用Delphi,呵呵。
虽然看了一段时间C++,可是觉得头大,看不懂。
1.ByteRa = array[0..0] of byte;是动态数组吗?不是,它前面有关键字 Type,所以它
成了一种类型,Integer类型应该很熟悉吧。ByteRa定义后和Integer一样,只不过是个
类型而已。
2.那么 Bytep0 = ^ByteRa; 这句话就可以理解成:指向ByteRa类型的一个指针,你可以
定义一个 i=PIntege,那么i就是整数型的指针了。同样它是在Type关键字中的,所以
ByteP0依然只是一个类型。它相当与这样一个类型: ^Integer;
3.定义buff: Bytep0;这句话,说明Buff是一个ByteRa的指针类型。只是一个指向Byte类
型的数组的地址(是个地址)。
4.通过GetMem(buff, Fsz);来个分配空间,这个空间从Buff这个地址开始,大小
为Fsz(Fsz是文件的大小)。BlockRead(F, buff^, Fsz);就将文件的内容以字节
(byte)的形式装载到Buff开始的地址.
5.ShowMessage(IntToStr(buff[i]));如果内存足够大,那么i多大都可以,i也可以是负
数,buff[i]是从buff开始往后的第i个地址的内容(如果i为负数,那么buff[i]是从
buff开始往前的第i个地址的内容)。
总之,要先理解:
type
ByteRa = array[0..0] of byte; //可以把这句话理解为定义一个新的类型。
Bytep0 = ^ByteRa; //这个新类型的指针表示形式。
就象我们用Integer一样,只不过Integer是系统定义好的。^Integer是Integer的指针表示而已。
>>>>>Bytep0 = ^ByteRa; //这个新类型的指针表示形式。
>>>>>就象我们用Integer一样,只不过Integer是系统定义好的。^Integer是Integer的指针表>>>>>示而已。这我可以理解。1.2.3.4.5也可以理解。关键是buff:Bytep0;也就是说为什么要把buff定义成Bytep0,也就是指向数组的一个指针?
定义成^integer不行吗?我的理解是定义成一个指向数组的指针有好处,就可以通过buff[i]来访问,而定义成^integer,就不能这样来访问。我的理解正确吗?
这样操作较麻烦,是这样吗?我还有一点想不通
>>>>>ByteRa = array[0..0] of byte; //可以把这句话理解为定义一个新的类型。
>>>>>Bytep0 = ^ByteRa; //这个新类型的指针表示形式。
为什么这样定义,就可以buff[i]来访问呢?
我的理解是定义成一个指向数组的指针有好处,就可以通过buff[i]来访问,而定义成^integer,就不能这样来访问。我的理解正确吗?
---------------------------------------------------------------------------
BlockRead是以字节(Byte)的形式读取文件内容的,如果该函数是以Integer的形式来读
取,那么就应该定义成 ^Integer了。------------------------------------------------
我还有一点想不通
>>>>>ByteRa = array[0..0] of byte; //可以把这句话理解为定义一个新的类型。
>>>>>Bytep0 = ^ByteRa; //这个新类型的指针表示形式。
为什么这样定义,就可以buff[i]来访问呢?
------------------------------------------------
通过buff[i]来访问,因为定义成ByteRa = array[0..0] of byte;Buff就指向Byte类
型的数组,数组自然可以用下标的方式来访问。
努力理解中。
Buff的地址----> |___________|---->存放ByteRa类型的数据
|___________|---->存放ByteRa类型的数据
|___________|---->存放ByteRa类型的数据
|___________|---->存放ByteRa类型的数据
…
如果定义改成:ByteRa = array[0..1] of byte,那么:
Buff的地址----> |___________|---->存放ByteRa类型的数据下标[0]
|___________|---->存放ByteRa类型的数据下标[1]
|___________|---->存放ByteRa类型的数据下标[0]
|___________|---->存放ByteRa类型的数据下标[1]
…