如何像C中的指针一样增加访问类型的地址?我是阿达新手......
procedure main is
type myarr is array(1..5)of integer; --creating array of 5 integer.
myarr_var:aliased myarr:=(2,5,7,9,0); --setting 5 values
type my_access is access all myarr; --creating access type (pointer)
var:my_access:=myarr_var'access; --holding address of 5 integer
begin;
-- since var holds the address of myarr_var now i want to increment
-- the address by adding 1 to print next value (5) as we do in c?
put((var+1).all); --???
-- i know this is bad but how to increment its base address of
-- var(pointer) so that it will point to next element 5?
end main;
Run Code Online (Sandbox Code Playgroud)
更新:我刚刚发现有一个标准包Interfaces.C.Pointers直接支持 C 风格的指针算术,现在我看到Marc C. 接受的答案涵盖了它的用法。Interfaces.C.Pointers您可能可以忽略我的答案,它讨论了如果 Ada不存在的话,如何在 Ada 中进行指针算术(在该语言的早期版本中,它不存在)。
如果您确实想对 Ada 访问类型执行 C 风格的指针算术,则可以使用 generic 包System.Address_To_Access_Conversions将对象指针类型转换为System.Address,并使用该System.Storage_Elements包对值执行类似 C 的算术System.Address。
请注意,目标对象类型是通用包的参数System.Address_To_Access_Conversions。包本身定义了访问类型。您无法定义自己的访问类型并使用它(至少不能直接使用)。
请记住,C 指针算术是以指向对象的大小为单位定义的。所以给出:
int arr[10];
int *ptr = &arr[0];
Run Code Online (Sandbox Code Playgroud)
指针值ptr + 3指向arr[3],它是int超过指向的位置(不一定是ptr三个字节)的三个大小的内存块。和运算符处理存储元素中的偏移量(很可能相当于 C 的“字节”)。"+""-"System.Storage_Elements
因此,如果您有一个 Ada指针,嗯,我的意思是访问值,它引用Integers 数组的一个元素,那么前进到该数组的下一个元素需要:
System.Address_To_Access_Conversions将访问类型转换为System.Address;"+"运算符 in将in 字节( )System.Storage_Elements的大小添加到值中;和Integer Integer'Max_Size_In_Storage_ElementsSystem.AddressSystem.Address_To_Access_Conversions将System.Address值转换回您的访问类型。另一种方法可能是编写 C 代码来执行您需要的任何指针算术,并用于Interfaces.C从 Ada 程序中调用该代码。
但很可能您不需要在Ada 中进行指针运算。C核心语言有指针运算;它甚至根据指针算术定义数组索引。艾达没有。在 Ada 中执行指针算术几乎没有充分的理由。只需让数组成为数组,然后让编译器找出如何生成访问其元素的最佳代码即可。(该代码可能涉及 CPU 指令级别的指针算术。)
实例化Interfaces.C.Pointers在Ada中进行C风格的指针算法.
最好用例子解释:
with Ada.Text_IO; use Ada.Text_IO;
with Interfaces.C.Pointers;
procedure Access_Pointer_Arithmetic is
type Myarr_Indices is range 1 .. 5;
type Myarr is array (Myarr_Indices range <>) of aliased Integer;
Myarr_Terminator : constant Integer := 0;
package Myarr_Pointer_Arithmetic is new Interfaces.C.Pointers
(Myarr_Indices, Integer, Myarr, Myarr_Terminator);
use Myarr_Pointer_Arithmetic;
Myarr_Var : aliased Myarr := (2, 5, 7, 9, 0);
Var : Myarr_Pointer_Arithmetic.Pointer :=
Myarr_Var(Myarr_Var'First)'access;
begin
Put_Line(Integer'Image(Var.all));
Increment(Var);
Put_Line(Integer'Image(Var.all));
Increment(Var);
Put_Line(Integer'Image(Var.all));
Increment(Var);
Put_Line(Integer'Image(Var.all));
Var := Var - 2;
Put_Line(Integer'Image(Var.all));
end Access_Pointer_Arithmetic;
Run Code Online (Sandbox Code Playgroud)
运行它:
C:\Ada\Sandbox\access_pointer_arithmetic
2
5
7
9
5
Run Code Online (Sandbox Code Playgroud)
该包提供单个递增/递减,ptrdiff_t的加法和减法,以及终止符指定和固定长度元素数组检索.
(介意阵列结束...... :-)