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上做了一下对比,结果如下:
可以看出
* 不能象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)
但字符数组是个例外:
这里,p := arr, p:= p + 2, p[2] 这几个表达式都合法了,并且结果与期望一致。
即使对于整数数组(其它也是,包括字符串数组),p := arr, p:= p + 2, p[2] 这几个表达式也都是合法的。
p := arr仍然是不合法的表达式,但 p + 2 和 p[2] 都可以了。
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] 都可以了。
相关文章推荐
- 访问元素:指向数组的指针与指向指针的指针
- C专家编程--指针和数组(四) 指针对数组的访问
- 1、打印二进制机器码,程序内存分析,大端序小端序,指针数组,数组指针,数组的三种访问方式,typedef,#if-0-#endif,求数组大小,括号表达式
- 数组的下标访问和指针访问方式效率分析比较
- 采用指针访问方式从键盘给数组a[N]输入数据,然后对元素值重新按逆序存放并输出
- 采用指针访问方式从键盘给数组a[N]输入数据,然后对元素值重新按逆序存放并输出 .
- 动态数组和指针转换(DELPHI)
- delphi与C++Builder指针和数组转换
- 从键盘输入十个整数存入一维数组中,求出它们的和及平均值并输出(要求用指针访问数组元素)?
- 多维数组元素的下标引用于指针访问
- 多维数组与指针——访问数组元素的指针表达式
- C语言中指针与数组之异同
- 指针访问多维数组
- [华为面试题_ND2]运行错误请检查是否存在数组越界非法访问_野指针乱访问_空指针乱访问等情况_java_scanner_error
- 利用指针访问数组
- 指针与数组是如何访问的——可以用extern int *p作为int p[N]的外部声明吗?
- c之指针与数组(2)Dynamic Data Structures: Malloc and Free--转载
- 7、数组1---(定义、a,&a,&a[0]区别、以指针形式访问和以下标形式访问)(
- Delphi 字符、字符串、字符数组和字符指针及其相关函数
- delphi 指针,数组,记录