您的位置:首页 > 编程语言 > Delphi

Delphi/FreePascal用指针访问数组的异同

2010-06-14 22:51 330 查看
前一段业余移植一个C写的 Total Commander 插件到 Double Commander, 后者是用FreePascal写的,虽然也可以直接用C来做这个插件,但俺还是有兴趣用freepascal重写一遍。最开始是用Lazarus 做IDE来写,为偷懒基本上是C函数到pascal函数来移,结构打算后面再调整,但移植完两个函数后调测时觉得Lazarus 这个IDE的调试功能实在太差,于是又改到先用Delphi 7来编译,于是发现了这两者在数组、指针方面的一些差异。刚才在Delphi 7, Delphi 2009和Freepascal 2.2.4上做了一下对比,结果如下:


Delphi 7

procedure TestIntArray;
var
arr : array[0..10] of integer;
p : PInteger;
i : integer;
s: string;
begin
for i:=0 to Length(arr)-1 do
arr[i] := i + 1000;

//  p := arr;  //error: Incompatible types: 'Array' and 'PInteger'
p := @arr;
Writeln(IntToStr(p^));
p := @arr[0]; //the same effect with above line?
Writeln(IntToStr(p^));

//  Writeln(IntToStr(p[2]));     //error: Array type required

//  p := p + 1;  //error: Operator not applicable to this operand type
Inc(p);

//  Writeln(IntToStr((p+1)^)); //error: Operator not applicable to this operand type
Writeln(IntToStr(p^));

Readln(s);
end;


可以看出

* 不能象C语言那样直接将数组赋值给指针 ( p := arr ),只能 ( p := @arr 或者 p := @arr[0] ),同样 p[2]也不是一个合法的表达式(错误信息为Array type required)
* 指针不能直接与数字做运算,比如p + 1这是不合法的(错误信息是Operator not applicable to this operand type),只能inc(p)或者dec(p),如果要增2就inc(p, 2)

但字符数组是个例外:

procedure TestCharArray;
var
arr : array[0..10] of Char;
p : PChar;
i : integer;
s: string;
begin
for i:=0 to Length(arr)-1 do
arr[i] := Chr(Ord('a') + i);

p := arr;  //OK!
p := @arr;
Writeln(p^);
p := @arr[0]; //the same effect with above line?
Writeln(p^);

p := p + 1;  //OK!
Inc(p);
Writeln(p[2]); //OK!

Writeln((p+1)^); //OK!

Readln(s);
end;


这里,p := arr, p:= p + 2, p[2] 这几个表达式都合法了,并且结果与期望一致。

FreePascal (2.2.4)

procedure TForm1.TestIntArray;
var
arr : array[0..10] of integer;
p : PInteger;
i : integer;
s: string;
begin
for i:=0 to Length(arr)-1 do
arr[i] := i + 1000;

p := arr;  //OK!
Memo1.Lines.Add(IntToStr(p^)); //output: 1000
p := @arr;
Memo1.Lines.Add(IntToStr(p^)); //output: 1000
p := @arr[0]; //OK!
Memo1.Lines.Add(IntToStr(p^)); //output: 1000

Memo1.Lines.Add(IntToStr(p[2])); //OK! output: 1002

p := p + 1;  //OK!
Inc(p);

Memo1.Lines.Add(IntToStr((p+1)^)); //OK! //output: 1003
Memo1.Lines.Add(IntToStr(p^));

//  Readln(s);
end;


即使对于整数数组(其它也是,包括字符串数组),p := arr, p:= p + 2, p[2] 这几个表达式也都是合法的。

Delphi 2009

在默认的选项下,Delphi 2009与Delphi 7相同,上述三种表达式都不支持。但可以打开一个编译选项$POINTERMATH:

{$POINTERMATH ON}
procedure TestIntArray;
var
arr : array[0..10] of integer;
p : PInteger;
i : integer;
s: string;
begin
for i:=0 to Length(arr)-1 do
arr[i] := i + 1000;

//  p := arr;  //error: Incompatible types: 'Array' and 'PInteger'
p := @arr;
Writeln(IntToStr(p^));{$POINTERMATH ON}
procedure TestIntArray;
var
arr : array[0..10] of integer;
p : PInteger;
i : integer;
s: string;
begin
for i:=0 to Length(arr)-1 do
arr[i] := i + 1000;

//  p := arr;  //error: Incompatible types: 'Array' and 'PInteger'
p := @arr;
Writeln(IntToStr(p^));
p := @arr[0]; //the same effect with above line?
Writeln(IntToStr(p^));

Writeln(IntToStr(p[2])); //OK in D2009

p := p + 1;  //OK in D2009
Inc(p);

Writeln(IntToStr((p+1)^)); //OK in D2009
//  Writeln(IntToStr(p^));

Readln(s);
end;
p := @arr[0]; //the same effect with above line?
Writeln(IntToStr(p^));

Writeln(IntToStr(p[2])); //OK in D2009

p := p + 1;  //OK in D2009
Inc(p);

Writeln(IntToStr((p+1)^)); //OK in D2009
//  Writeln(IntToStr(p^));

Readln(s);
end;


p := arr仍然是不合法的表达式,但 p + 2 和 p[2] 都可以了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐