当前位置:首页 > 服务端 > Delphi/FreePascal用指针访问数组的异同

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

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

作者:巴蛮子
来源链接:https://www.cnblogs.com/bamanzi/archive/2010/06/14/delphi-freepascal-pointor-to-array.html

版权声明:
1、Java侠(https://www.javaxia.com)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。





本文链接:https://www.javaxia.com/server/124848.html

分享给朋友: