我需要一些解决这些问题的答案。我在使用记录在Ada中编程时遇到了这些错误

时间:2014-06-17 10:29:30

标签: ada

我是Ada编程的新手。这是我的一个程序的ADA代码,它在执行时输入一个足球传奇名称时给出了一个列表。但是我收到以下错误。请帮帮我:

发现的一些错误是: 1.Discriminants必须具有离散或Access类型 2.组件“在记录声明结束前不能使用FBClub 3.变体部分中的歧视必须是离散的部分 4.“玩家”未定义 5.“pos”未定义。 6.没有候选人的解释符合sctuals:=>在“类型播放器名称...”

行调用继承操作“to_string”
with Ada.Text_Io; use Ada.Text_Io; 
with Ada.Integer_Text_Io; use Ada.Integer_Text_Io; 
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;

Procedure football_record is 
type Position is (Goalkeeper,Midfielder,Forward,Defender);
type playernames is new Unbounded_String;
type FBClubs is (ACMilan,Man_United,Aresnal,ParisSt.Germain,Real_Madrid,Liverpool,Chelsea,Man_City,Lille,
Tottenham,Ajax,Juventus,Dortmund,Roma,Santos,Roma,Bayern_Munich,Inter_Milan);
type countries is (England,Argentina,Brazil,France,Italy,Portugal,Spain,Germany,Iran,Japan);
type fbplayer(player:playernames) is 
   record 
WCAppearances:Integer;
pos:Position;
country:countries;
fbclubs:FBClubs;
case player is 
 when "David Beckham" =>
        country:countries:=England;
        WCAppearances:Integer:=3;
        pos:Position:=Midfielder;
        fbclubs:FBClubs:=ACMilan &"+" & Man_United &"+" & Real_Madrid &"+"& ParisSt.Germain;
 when "Lionel Messi" =>
        country:countries:=Argentina;
        WCAppearances:Integer:=1;
        pos:Position:=Forward;
        fbclubs:FBClubs:=Barcelona;
.....and some other 12 players(legends)..
when others =>
       country:countries:=Nil;
       WCAppearances:Integer:=Nil;
       pos:Position:=Nil;
       fbclubs:FBClubs:=Nil;
end case; 
end record; 

begin
Get(player);
Put_Line(To_String(Integer'Image(player)));
Put_Line(To_String(Integer'Image(FBClubs'Image(fbclubs)));
Put_Line(To_Unbounded_String(Position'Image(pos)));
end football_record;

1 个答案:

答案 0 :(得分:5)

最大的问题是你将代码与类型声明混合在一起。

在Ada中,将case放在record内仅适用于变种记录;这些记录在某些情况下存在某些字段但在其他情况下不存在。例如:

type Employee_Type is (Regular, Manager);
type Employee (Emp_Type : Employee_Type) is record
     Name : Unbounded_String;
     case Emp_Type is
         when Manager =>
              Managerial_Level : Integer;
         when Regular =>
              null;
     end case;
end record;

这是一个变体记录;我们在这里假设有两种员工,而Managerial_Level字段仅适用于其中一种。类型为Regular的记录根本不会有Managerial_Level字段。

此语法不是用于返回字段的不同的语法。相反,您需要在语句中执行此操作,通常在procedurefunction(或包初始化,或允许语句的其他位置)。

由于您没有使用变体记录语法,因此您无需将player作为判别式。无论如何它都行不通;在Ada中,“判别式”(在我的示例中类似Emp_Type)必须是离散类型,如整数或枚举类型(Employee_Type是枚举类型),或访问(访问判别式是一个先进的概念)。它不能是Unbounded_String。所以你想让player成为常规字段:

type fbplayer is record
    player : Unbounded_String;
    pos : Position;
    country : countries;
    clubs : FBClubs;   -- Note name change!
    WCAppearances : Integer;
end record;

并创建一个填写字段的程序:

procedure Fill_In_Player(P : in out fbplayer; Player : Playernames) is
begin
    P.Player := Player;
    if Player = "David Beckham" then
        P.country := England;
        P.WCAppearances := 3;
        P.pos = Midfielder;
        P.clubs := ??? -- see below
    elsif Player = "Lionel Messi" then
        ------- etc.
    elsif ------
    end if;
end Fill_In_Player;

然后在您拥有Fill_In_Player并且想要设置记录字段时调用Player。您必须编写语句才能执行此操作;你不能在记录声明中做到这一点。

请注意,在Ada中,case语句只能用于整数或枚举类型。您不能像其他语言允许的那样使用它们来测试字符串。

Ada不会在标识符或关键字中将小写字母和大写字母视为相同。因此,fbclubsFBClubs的名称相同,您无法声明字段

fbclubs : FBClubs;

因为名称冲突。我改名了。

最后,看起来您希望FBClubs拥有多个俱乐部。但FBClubs是枚举类型,因此一次只能保存一个值。如果你希望每个玩家记录都包含一个俱乐​​部列表,你需要做一些其他事情,比如使用Ada的容器类型之一(如Ada.Containers.Vectors.Vector)或类似

type Set_Of_Clubs is array(FBClubs) of Boolean;

如果玩家为该俱乐部效力,则每个数组值为true

我不确定会处理所有错误,但看起来你已经做了很多工作。