• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

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

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

前一段业余移植一个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] 都可以了。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
图像复原MATLAB实现发布时间:2022-07-18
下一篇:
Delphi与DirectX之DelphiX(35):TDIB.Saturation();发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap