Cours 6: Types articles et pointeurs.
Objectif: Type Record, composant. Paramètres record.
Exemple: date du lendemain.
Type pointeur. Type incomplet.
Le type Record permet de regrouper plusieurs objets de types différents.
Extrait du manuel de référence (RM95):
record_type_definition ::= [[abstract] tagged] [limited] record_definition
record_definition ::=
record
component_list
end record
| null record
component_list ::=
component_item {component_item}
| {component_item} variant_part
| null;
component_item ::= component_declaration | representation_clause
component_declaration ::=
defining_identifier_list : component_definition [:= default_expression];
Extrait du manuel de référence (RM95):
type Date is
record
Day : Integer range 1 .. 31;
Month : Month_Name;
Year : Integer range 0 .. 4000;
end record;
type Complex is
record
Re : Real := 0.0;
Im : Real := 0.0;
end record;
Tomorrow, Yesterday : Date;
A, B, C : Complex;
-- both components of A, B, and C are implicitly initialized to zero
Exemple: Calcul de la date du lendemain.
type Nom_de_Mois is (Janvier, Fevrier, Mars, Avril, Mai, Juin,
Juillet, Aout, Septembre, Octobre, Novembre, Decembre);
subtype Deux_Siecles is Integer range 1901..2099;
subtype Quantieme is Integer range 1..31;
type Date is record
Jour: Quantieme;
Mois: Nom_de_Mois;
Annee: Deux_Siecles;
end record;
Function Date_du_Lendemain(D: Date) return Date is
Demain: Date;
Fin_de_Mois: Quantieme;
Function Bissextile(A: Deux_Siecles) return Boolean is
--valide seulement pour A dans [1901..2099]
--seule annee seculaire: 2000, bissextile
begin
return ((A mod 4) = 0);
end Bissextile;
begin
case D.Mois is
when Avril | Juin | Septembre | Novembre =>
Fin_de_Mois := 30;
when Fevrier =>
if Bissextile(D.Annee) then
Fin_de_Mois := 29;
else
Fin_de_Mois := 28;
end if;
when others =>
Fin_de_Mois := 31;
end case;
if (D.Jour /= Fin_de_Mois) then
Demain.Jour := D.Jour + 1;
Demain.Mois := D.Mois;
Demain.Annee := D.Annee;
else
Demain.Jour := 1;
if (D.Mois /= Decembre) then
Demain.Mois := Nom_de_Mois'Succ(D.Mois);
Demain.Annee := D.Annee;
else
Demain.Mois := Janvier;
Demain.Annee := D.Annee + 1;
end if;
end if;
return Demain;
end Date_du_Lendemain;
Une déclaration de type peut être spécifiée en deux fois.
On commence par une déclaration incomplète qui ne définit que le nom.
Extrait du manuel de référence (RM95):
incomplete_type_declaration ::= type defining_identifier [discriminant_part];
Le type accès permet de désigner des objets (ou des sous-programmes) par leur adresse.
Extrait du manuel de référence (RM95):
access_type_definition ::=
access_to_object_definition
| access_to_subprogram_definition
access_to_object_definition ::=
access [general_access_modifier] subtype_indication
general_access_modifier ::= all | constant
access_to_subprogram_definition ::=
access [protected] procedure parameter_profile
| access [protected] function parameter_and_result_profile
access_definition ::= access subtype_mark
Extrait du manuel de référence (RM95):
type Cell; -- incomplete type declaration
type Link is access Cell;
type Cell is
record
Value : Integer;
Succ : Link;
Pred : Link;
end record;
Head : Link := new Cell'(0, null, null);
Next : Link := Head.Succ;
Exemple: insertion en place dans une liste simplement chaînée.
type Cellule;
type Liste is access Cellule;
type Cellule is record
Valeur: Integer;
Suivant: Liste;
end record;
Procedure Ajouter_en_Place(L: in out Liste; V: Integer) is
--insérer V en place dans la liste L triée
NL: Liste := new Cellule'(V, null);
--new Cellule: allocation dynamique d'un objet de type Cellule
--Cellule'(V,null): agrégat pour fixer la valeur initiale de l'objet alloué
CL: Liste:= L;
PL: Liste;
begin
if CL=null then
L:= NL;
else
while (CL.Valeur <= V and then CL.Suivant /= null) loop
PL:= CL;
CL:= CL.Suivant;
end loop;
if (CL.Valeur <= V) then --ajout en queue, après CL
CL.Suivant:= NL;
else --lier la fin de liste derrière la nouvelle cellule
NL.Suivant:= CL;
if (PL=null) then --ajout en tête
L:= NL;
else --ajout au centre, entre PL et CL
PL.Suivant:= NL;
end if;
end if;
end if;
end Ajouter_en_Place;