如何在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;
答案 0 :(得分:5)
实例化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;
运行它:
C:\Ada\Sandbox\access_pointer_arithmetic
2
5
7
9
5
该软件包提供单个递增/递减,ptrdiff_t的加法和减法,以及终结器指定和固定长度元素数组检索。
(介意运行阵列结束......: - )
答案 1 :(得分:4)
更新:我刚发现那里有一个直接支持C风格指针算法的标准包Interfaces.C.Pointers
,现在我看到Marc C.'s accepted answer涵盖了它用法。您可以忽略我的答案,该答案讨论了如果Interfaces.C.Pointers
不存在(在早期版本的语言中,它没有),您可以在Ada中进行指针算术。
如果确实希望对Ada访问类型执行C风格的指针算法,则可以使用通用包System.Address_To_Access_Conversions
将对象指针类型转换为System.Address
,以及System.Storage_Elements
包对System.Address
值执行类C算术。
请注意,目标对象类型是System.Address_To_Access_Conversions
通用包的参数。包本身定义了访问类型。您无法定义自己的访问类型并使用它(至少不能直接使用)。
请记住,C指针算术是以指向对象的大小为单位定义的。所以给出:
int arr[10];
int *ptr = &arr[0];
指针值ptr + 3
指向arr[3]
,这是三个int
大小的内存块,超过ptr
点不必须三个字节。 "+"
中的"-"
和System.Storage_Elements
运算符可以处理存储元素中的偏移量(很可能等同于C&#34;字节&#34;)。
所以如果你有一个Ada 指针,嗯,我的意思是访问值,它指的是Integer
s数组的元素,然后前进到 next < / em>该数组的元素需要:
System.Address_To_Access_Conversions
将访问类型转换为System.Address
; "+"
中的重载System.Storage_Elements
运算符将Integer
的字节数(Integer'Max_Size_In_Storage_Elements
)添加到{{1}价值;和System.Address
将System.Address_To_Access_Conversions
值转换回您的访问类型。另一种方法可能是编写C代码来执行您需要的任何指针算法,并使用System.Address
从您的Ada程序中调用该代码。
但很有可能你不需要在Ada中进行指针运算。 C在核心语言中有指针算术;它甚至根据指针算法定义了数组索引。阿达没有。在Ada中执行指针算法很少是一个很好的理由。让数组成为数组,让编译器弄清楚如何生成访问其元素的最佳代码。 (该代码可能涉及CPU指令级别的指针运算。)