Pointers Ada数组访问:指向数组中特定项的指针,位置根据输入参数动态变化。

Pointers Ada数组访问:指向数组中特定项的指针,位置根据输入参数动态变化。,pointers,ada,Pointers,Ada,我在Ada95工作,我很难找出指针 我有如下代码: type vector is array (1 .. 3) of integer; type vector_access is access vector; my_vec : vector; procedure test is pointer : vector_access := my_vec'access; begin ... end; 这无法编译指针的定义,如下所示 “ACCESS的前缀必须是对象的别名

我在Ada95工作,我很难找出指针

我有如下代码:

type vector is array (1 .. 3) of integer;   
type vector_access is access vector;

my_vec : vector;

procedure test is  
  pointer : vector_access := my_vec'access;  
begin   
  ...  
end;
这无法编译指针的定义,如下所示

“ACCESS的前缀必须是对象的别名视图或表示具有非内在调用约定的子程序”

如果我将向量本身的定义更改为:

my_vec : aliased vector  
它现在返回编译器错误:

X'ACCESS的预期类型,其中X表示对象的别名视图,必须是常规ACCESS类型


在一天结束时,我真正需要的是一个指向数组中特定项的指针,该位置基于输入参数是动态的。有人能给我指出正确的方向吗?

我想我找到了,因为其他人遇到了同样的问题

答案与具体的别名有关。数组声明需要:

type vector is array (1 .. 3) of aliased integer;

为了确保整数存储在内存中,而不是寄存器中。

如果使用GNAT,“必须是常规访问类型”后面的错误消息应该为您提供解决方案:

将“全部”添加到“向量访问”类型中 在第行定义

这样你就可以得到:

type Vector_Access is access all Vector;
使用“all”来指定一般访问类型与Ada中的动态内存分配池有关。如果您不关心动态内存分配池,那么就不用担心它,只需在访问类型定义中包含“all”

我不确定这是否是您在一天结束时寻找的内容的一部分,但您知道在大多数情况下,Ada的访问(指针)类型用于处理动态分配的内存,对吗

因此,您不必将my_vec指向别名变量,而是动态分配它:

Pointer_2_Dynamic : vector_access := new Vector;
通过这种方式,您可以在运行时动态分配所需的对象,并轻松处理大小不同的对象(尽管您需要不同的向量定义来实现这一点:

type Dynamic_Vector is array (Natural range <>) of Integer;
type Dynamic_Vector_Access is access Dynamic_Vector;

N : Natural := 10; -- Variable here, but could be a subprogram parameter.
Dyn_Vector : Dynamic_Vector_Access := new Dynamic_Vector(1..N);
类型动态_向量是整数的数组(自然范围);
类型Dynamic_Vector_Access为Access Dynamic_Vector;
N:Natural:=10;--此处为变量,但可以是子程序参数。
动态向量:动态向量访问:=新的动态向量(1..N);

好的。专家Cish编码器关于Ada的第一课:Ada参数不同于Cish参数。在C中,(预参考参数)每一个参数都相当于一个Ada“in”参数,还有一个附加条件,即C编译器必须始终愚蠢地在堆栈上传递整个内容,不管它有多大。因此,可怜的C代码编写者会把它牢牢地钉在脑子里,永远不会将大对象直接传递到子例程中,而总是使用指针

Ada不同。您可以告诉编译器您希望如何访问参数(只读-‘in’、只读-‘out’或读写-‘in out’)。但是,这与参数的传递方式无关。参数传递机制取决于编译器,编译器将选择最有效的方式来实现它。。实际上,在几乎所有平台上,这意味着对寄存器来说太大的任何东西都将通过引用传递。但这是一个实现细节il,这是编译器的事,不是你的事。你甚至不应该去想它,除非在非常罕见的情况下

所以,咬紧牙关,把数组作为一个
in-out
参数来传递。相信我,你会喜欢它的

type vector is array (natural range <>) of integer;
my_vec : vector(1..3); 

procedure test (subject : in out vector) is   
begin    
  ...   
end; 
类型向量是整数的数组(自然范围);
my_vec:vector(1..3);
程序测试(主题:输入输出向量)为
开始
...   
结束;
Ada被设计为在几乎所有情况下都非常可用,而不需要指针,并且除了极少数非常罕见的情况外,在所有情况下都可以使用,而不需要指针来堆叠分配的对象

前者相当不安全(来自未分配指针和内存泄漏的危险),而后者更不安全(堆栈对象可能在指针之前超出范围,即使它们没有超出范围,一个小的大小错误也会损坏整个程序)。在Ada中,您仍然可以同时使用这两种语言,但与许多语言不同的是,它旨在使不安全的事情需要您多做一些工作,并使非常不安全的事情成为编写的主要PITA


例如,如果您只是动态分配整个数组,您就不必愚弄这个
别名
所有
业务。此外,如果您只想将数组传递到子例程中,您可以将其作为参数传递,甚至不必愚弄动态分配和解除分配。再次,Ada编译器足够智能,可以通过引用传递大型对象(是的,即使您在中指定了
)。这需要C/C++程序员调整态度,他们习惯于告诉他们的蠢货编译器不要在堆栈上传递10meg对象。你必须学会让Ada编译器担心如何有效地传递参数,你只需要担心如何编写好代码。

我不知道你在用什么编译器,但这不太可能是GNATGPL2010,因为对向量声明的更改会产生完全相同的错误。使用“别名”与指定编译器是在内存中还是在寄存器中维护变量无关,它只是用来标记可能是访问值目标的变量——这可能会影响编译器如何分配其存储,但除此之外没有其他含义。事实上,我使用的是GreenHills AdaMulti的旧版本(…不是自愿的)。谢谢你对别名关键字的澄清;我刚刚从其他网站上找到的内容中删除。谢谢你的提示。all关键字绝对是我所寻找的内容的一部分。不幸的是,我实际上受到总体需求的限制,无法分配任何动态内存,