You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何定义含两个多维无约束数组的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:02:57