1

我有一个关于声明性部分、函数和包的查询。我有一个如下所示的包裹。由于 Compute_X1 函数的复杂性,我创建了一个“独立的”来计算这个函数。从 Compute_X1 返回的值是 X1,将在函数 J21 中使用(J21 将 X1 作为第一个参数)。

包装规格:

package Compute_Jacobian is

--compute X1
function Compute_X1 ( Force_Applied, Forcing_Frequency: Long_Float) return Long_Float;

--- use X1 in J21
function J21 ( X1, Forcing_Frequency, Natural_Frequency : Long_Float) return Long_Float;

end Compute_Jacobian;

包体为:

package body Compute_Jacobian is
 --compute X1

function Compute_X1 ( Force_Applied, Forcing_Frequency: Long_Float) return Long_Float is separate;

X1 := Compute_X1 ( Force_Applied, Forcing_Frequency);


function J21 ( X1, Forcing_Frequency, Natural_Frequency : Long_Float) return Long_Float is separate;

end Compute_Jacobian;

我已经为 Compute_X1 和 J21 创建了存根。

在编译包体 Compute_Jacobian.adb 时,我收到以下错误消息:

12.    X1 := Compute_X1 ( Force_Applied, Forcing_Frequency);
       |
    >>> statement not allowed in declarative part

我的问题是如何计算 X1 并将其用于计算函数 J21。

我可以尝试直接在“主”代码(此处未显示)中计算 X1(从那里创建“独立”),然后将其用作计算 J21 的正常参数。但是我想要上面的结构(在我上面的帖子中),并在 Compute_Jacobian 包中计算 X1。

非常感谢...

4

1 回答 1

2

好吧,编译器会告诉你问题出在哪里:-)

您正试图在只允许声明的代码区域中执行赋值语句。

至少我没有看到您对 X1 的声明(尽管这可能是因为您没有在上面的代码中摘录它),也没有看到分配给 Force_Applied 和 Forcing_Frequency 的声明和值。

这可以修复,使其编译接近原样:

X1 : Long_Float := Compute_X1 ( Force_Applied, Forcing_Frequency);

或者,通过在包体中添加一个初始化块:

package body Computer_Jacobian is
    ...
    X1 : Long_Float;
    ...
begin
   X1 := Compute_X1 ( Force_Applied, Forcing_Frequency);
end Compute_Jacobian;

但老实说,我真的不认为这两者都是你真正想要的。

在您的主程序中,您可以只声明 X1(以及作为参数传递的变量),然后调用您的 Compute 函数,例如(警告,未编译)

with Compute_Jacobian;
procedure Do_Computations is

  Force_Applied     : Long_Float := 1.0;
  Forcing_Frequency : Long_Float := 10.0;
  Natural_Frequency : Long_Float := 5.0;

  X1  : Long_Float;
  J21 : Long_Float;

begin
   X1  := Compute_Jacobian.Compute_X1 (Force_Applied, Forcing_Frequency);
   J21 := Compute_Jacobian.Compute_J21 (X1, Forcing_Frequency, Natural_Frequency);
end Do_Computations;

这是获得您可能正在寻找的东西的一种方法。

或者,如果 X1 仅在 Compute_J21 中使用,您应该调用 Compute_X1 作为在该函数中执行的第一个语句之一(或作为 X1 声明的初始化)(并将 Force_Applied 而不是 X1 作为参数传递给 Compute_J21):

function Compute_J21 (Force_Applied, 
                      Forcing_Frequency,
                      Natural_Frequency : Long_Float)
                                   return Long_Float is

   -- Declarations...
   X1 : Long_Float := Compute_X1(Force_Applied, Forcing_Frequency);

begin
   -- Computations that utilize X1...

end Compute_J21;

还有一个关于使用“分离”的注释......我理解由于它们的复杂性而将这些功能实现分开的冲动,但我仍然建议不要这样做。它只是添加了另一个文件来跟踪,如果你使用 GNAT,你不会通过尝试单独编译它们来获得任何性能提升,因为整个包体最终都会得到处理,现在使用“is separate”在主流 Ada 编程中相当罕见。这个答案涵盖了您之前提出的问题中的一些内容。

于 2010-09-23T13:21:03.337 回答