如何定义含两个多维无约束数组的Ada结构体并传递给过程
Ada新手问题:包含无约束数组的结构体定义与传递解决方案
嘿,作为Ada新手碰到这个问题太正常了!咱们先看看编译器报错的原因,再一步步解决它~
你的编译器报错unconstrained subtype in component declaration,意思是记录类型里不能直接包含无约束的数组类型——因为无约束数组的大小是不确定的,这样整个记录的大小也没法确定,Ada的强类型系统不允许这种情况。不过有两种常用的解决办法,咱们一个个说:
方法一:使用判别式(Discriminant)约束数组大小(推荐)
这是最符合Ada风格的做法,通过给记录添加判别式,来指定数组的维度和长度,让记录的大小变得确定。
修改后的包规范:
package SDR_Treatment is ----------------------------------------------------------------------------- -- CONSTANTS - ----------------------------------------------------------------------------- GEO_SPACIAL_AND_SPEED: constant Natural := 1; --Type of Data ----------------------------------------------------------------------------- type Slicing_Pointers is array (Positive range <>) of Integer; type Region is array (Positive range <>, Positive range <>, Positive range <>) of Integer; -- 添加判别式来约束两个数组的大小 type Location_and_Speed_Region ( SP_Length : Positive; -- Slicing_Pointers的长度 Dim1, Dim2, Dim3 : Positive -- Region的三个维度大小 ) is record Region_Id : Natural := 0; SP: Slicing_Pointers(1 .. SP_Length); -- 用判别式约束数组范围 Rig: Region(1 .. Dim1, 1 .. Dim2, 1 .. Dim3); -- 约束三维数组的每个维度 end record; procedure SDR_Encoding(lsr: in out Location_and_Speed_Region); end SDR_Treatment; -----------------------------------------------------------------------------
然后修正包体里的拼写错误(你把Location_and_Speed_Region写成了Location_and_Speed_Rigion,少了个e):
with Ada.Text_IO; use Ada.Text_IO; package body SDR_Treatment is procedure SDR_Encoding(lsr: in out Location_and_Speed_Region) is begin Ada.Text_IO.Put_Line("Encoding SDR..."); -- 现在可以正常访问lsr.SP和lsr.Rig了,比如: -- lsr.SP(1) := 42; -- lsr.Rig(1,1,1) := 100; end SDR_Encoding; end SDR_Treatment;
使用这个记录的时候,你需要在声明变量时指定判别式的值,比如:
declare -- 声明一个SP长度为5,Region是3x3x3的记录实例 My_Region : Location_and_Speed_Region(SP_Length => 5, Dim1 => 3, Dim2 => 3, Dim3 => 3); begin SDR_Encoding(My_Region); end;
方法二:使用访问类型(指针)动态分配数组
如果你的数组大小需要在运行时动态调整,或者需要共享数组实例,可以用访问类型(类似其他语言的指针)来存储数组的引用。
修改后的包规范:
package SDR_Treatment is ----------------------------------------------------------------------------- -- CONSTANTS - ----------------------------------------------------------------------------- GEO_SPACIAL_AND_SPEED: constant Natural := 1; --Type of Data ----------------------------------------------------------------------------- type Slicing_Pointers is array (Positive range <>) of Integer; type Region is array (Positive range <>, Positive range <>, Positive range <>) of Integer; -- 定义指向无约束数组的访问类型 type Slicing_Pointers_Access is access Slicing_Pointers; type Region_Access is access Region; type Location_and_Speed_Region is record Region_Id : Natural := 0; SP: Slicing_Pointers_Access; -- 存储数组指针 Rig: Region_Access; end record; procedure SDR_Encoding(lsr: in out Location_and_Speed_Region); end SDR_Treatment; -----------------------------------------------------------------------------
包体同样修正拼写错误:
with Ada.Text_IO; use Ada.Text_IO; package body SDR_Treatment is procedure SDR_Encoding(lsr: in out Location_and_Speed_Region) is begin Ada.Text_IO.Put_Line("Encoding SDR..."); -- 访问数组需要通过.all,比如: -- lsr.SP.all(1) := 42; -- lsr.Rig.all(1,1,1) := 100; end SDR_Encoding; end SDR_Treatment;
使用时需要先动态分配数组:
declare -- 分配一个长度为5的Slicing_Pointers数组 My_SP : constant Slicing_Pointers_Access := new Slicing_Pointers'(1, 2, 3, 4, 5); -- 分配一个3x3x3的Region数组,所有元素初始化为0 My_Region_Data : constant Region_Access := new Region'(1..3, 1..3, 1..3 => 0); -- 初始化记录 My_Record : Location_and_Speed_Region := (Region_Id => 1, SP => My_SP, Rig => My_Region_Data); begin SDR_Encoding(My_Record); -- 注意:如果需要手动释放内存,可以使用Ada.Unchecked_Deallocation,部分编译器也支持自动管理 end;
额外小修正
你包体里的过程参数拼写错误:Location_and_Speed_Rigion应该是Location_and_Speed_Region,少了字母e,这个也要修正,不然编译也会报错哦~
内容的提问来源于stack exchange,提问作者Sasha Dardik
相关产品推荐
相关产品推荐

