Types Structurés et Enregistrements

Page 1 sur 8Lecteur de document UniversityLib

Types Structurés et Enregistrements

Algorithmic Structures · notes

Voir tous les documents en programmation

S. Laporte

Type structurés et enregistrements

DAIGL

Les types structurés et les enregistrements

Introduction

Contrairement aux tableaux qui sont des structures de données dont tous les éléments sont de même type, les enregistrements sont des structures de données dont les éléments peuvent être de type différent et qui se rapportent à la même entité sémantique (analogie avec Merise).Les éléments qui composent un enregistrement sont appelés champs.

Avant de déclarer une variable enregistrement, il faut avoir au préalable définit son type, c'est à dire le nom et le type des champs qui le compose. Le type d'un enregistrement est appelé type structuré. (Les enregistrements sont parfois appelé structures, en analogie avec le langage C)

Préalable: déclaration d'un type structuré

Jusqu'à présent, nous n'avons utilisé que des types primitifs (caractères, entiers, réels, chaînes) et des tableaux de types primitifs. Mais il est possible de créer nos propres types puis de déclarer des variables ou des tableaux d'éléments de ce type.

Pour ce faire, il faut déclarer un nouveau type, fondé sur d'autres types existants. Après l’avoir défini, on peut dès lors utiliser ce type structuré tout autre type normal en déclarant une ou plusieurs variables de ce type. Les variables de type structuré sont appelées enregistrements.

La déclaration des types structurés se fait dans une section spéciale des algorithmes appelée Type, qui précède la section des variables (et succède à la section des constantes). Si l’algorithme comporte des sous-programmes, les types et les constantes sont déclarées en dehors du programme.

Syntaxes :

Type Structure nom_type

nom_champ1: type_champ1 … nom_champN: type_champN

Exemple:

FinStruct

Type Structure tpersonne

nom : chaîne prénom : chaîne âge : entier

FinStruct

I. Déclaration d'un enregistrement à partir d'un type structuré

Une fois qu'on a défini un type structuré, on peut déclarer des variables enregistrements exactement de la même façon que l'on déclare des variables d'un type primitif.

1

S. Laporte

Type structurés et enregistrements

DAIGL

Syntaxe Var nom_var : nom_type

Exemple:

Var pers1, pers2, pers3 : tpersonne

Représentation: les enregistrements sont composés de plusieurs zones de données, correspondant aux champs

pers1.nom

pers1.age

pers1

pers2

pers2.nom

pers2.age

Il est naturel de faire une analogie avec la notion de table du modèle relationnel, ou d'entité du modèle entité-association (MCD)

Soit l'entité suivante:

PRODUIT

légende:

code lib paht pvht txtva

code: code alphanumérique du produit lib: libéllé paht: prix d'achat hors taxes pvht: prix de vente hors taxes txtva: taux de TVA applicable

Voici comment déclarer deux occurrences (variables enregistrements) du type structuré correspondant à cette entité.

// Il faut d'abord définir le type structuré correspondant:

Type

Structure produit code: chaîne lib: chaîne paht: réel pvht: réel txtva: réel FinStruct

// Ensuite il est possible de déclarer deux variables de ce type Var prod1, prod2 : produit

On peut donc dire que prod1 et prod2 sont deux occurrences de l’entité Produit. Cependant, l’analogie se limite ici. En particulier, dans une entité, toutes les propriétés ne possèdent pas un statut équivalent. Ainsi, il existe des identifiants, c’est à dire des propriétés possédant une valeur unique par occurrence, et ceci est spécifié logiquement lors du passage au modèle relationnel. Ici, il n’y a pas de possibilité de préciser quel champ est identifiant du type structuré. Si on n’y prend pas garde, nous pouvons dés lors créer des occurrences possédant la même valeur pour la propriété Code, ce qui peut poser problème au niveau de notre application.

2

S. Laporte

Type structurés et enregistrements

Publicité

DAIGL

II. Manipulation d'un enregistrement

La manipulation d'un enregistrement se fait au travers de ses champs. Comme pour les tableaux, il n'est pas possible de manipuler un enregistrement globalement, sauf pour affecter un enregistrement à un autre de même type (ou le passer en paramètre). Par exemple, pour afficher un enregistrement il faut afficher tous ses champs un par un.

A. Accès aux champs d'un enregistrement

Alors que les éléments d'un tableau sont par l’intermédiaire de leur indice, les champs d'un enregistrement sont accessibles à travers leur nom, grâce à l'opérateur '.'

nom_enregistrement . nom_champ représente la valeur mémorisée dans le champ de l'enregistrement

Par exemple, pour accéder à l'âge de la variable pers2, on utilise l'expression:

pers2.âge

Remarque : la lecture d'une telle expression se fait de droit à gauche : l'âge de la personne2.

? Attention : le nom d'un champ est TOUJOURS précédé du nom de l'enregistrement auquel il appartient. On ne peut pas trouver un nom de champ tout seul, sans indication de l'enregistrement.

Les champs d'un enregistrement, tout comme les éléments d'un tableau, sont des variables à qui on peut faire subir les mêmes opérations (affectation, saisie, affichage,…).

Exemple 1: Programme de saisie des données concernant les personnes pers1 et pers2, puis affichage de la différence d'âge entre ces deux personnes

Programme Exemple Type Structure tpersonne

nom : chaîne prénom : chaîne âge : entier

FinStruct

Var pers1, pers2 : tpersonne

Début

Aff "Entrez le nom puis l'age de la personne 1" Saisir pers1.nom, pers1.age // il est impossible d'écrire Saisir pers1 Aff "Entrez le nom puis l'âge de la personne 2" Saisir pers2.nom, pers2.age Aff "La différence d'âge entre ", pers1.nom, " et ", pers2.nom, " est de " Si pers1.age > pers2.age Alors Aff pers1.age – pers2.age, " ans " Sinon Aff pers2.age – pers1.age, " ans " FinSi

Fin

Rappel : il est possible d'affecter un enregistrement à un autre de même type. Là, il serait correct d'écrire pers1 ? pers2

3

S. Laporte

Type structurés et enregistrements

DAIGL

B. un enregistrement comme champ d'une structure

Supposons que dans le type personne, nous ne voulions plus l'âge de la personne, mais sa date de naissance. Une date est composée de trois variables (jour, mois, année) indissociables1. Une date correspond donc à une entité du monde réel qu'on doit représenter par un type enregistrement à 3 champs. Si on déclare le type date au préalable, on peut l'utiliser dans la déclaration du type personne pour le type de la date de naissance.

Un type structuré peut être utilisé comme type pour des champs d'un autre type structuré

TYPE Structure date jour: entier mois: chaîne année: entier FinStuct

Structure personne nom: chaîne ddn: date FinStruct

Pour accéder à l'année de naissance d'une personne, il faut utiliser deux fois l'opérateur '.'

pers1.ddn.année

Il faut lire une telle variable de droite à gauche : l'année de la date de naissance de la personne 1.

Exemple Complet Un produit (cf. ex précédents) est livré par un seul fournisseur. Un fournisseur est caractérisé par son code, sa raison sociale et son numéro de téléphone.

Structure fournisseur

code_frs : chaine raison_sociale: chaine tel: chaine

FinStruct

Structure Produit

code: chaîne lib: chaîne paht: réel pvht: réel txtva: réel frs: fournisseur

FinStruct

Var p: produit

Voilà l'instruction qui permet d'afficher le numéro de téléphone du fournisseur du produit p.frs.tel

Aff "téléphone du fournisseur de ", p.lib, " : ", p.frs.tel

Fournisseur, qui est en dépendance fonctionnelle sur Produit, est un champ de la structure produit.

1 En supposant que le type Date n'existe pas.

4

S. Laporte

Type structurés et enregistrements

DAIGL

Voilà le MCD correspondant.

1,1

Publicité

est livré par

FOURNISSEUR

1,n

code_frs raison_sociale tel

PRODUIT

code lib paht pvht txtva

C. Un tableau comme champ de structure

Il est possible aussi qu'un champ de type structuré soit de type tableau, voire tableau structuré ! Exemple d'un type structuré contenant un tableau simple Imaginons une structure mémorisant des critères géographiques de villes (altitude, type de climat, …). Certains de ces critères pourraient pertinemment être mémorisés pour chaque mois de l'année (par exemple température moyenne, précipitations moyennes, …)

Structure Ville Nom : chaîne Alt : entier Climat : Chaîne Temp : tableau[1..12] de réel Précip : tableau[1..12] de réel FinStruct

//Altitude moyenne //type de climat //température moyenne par mois //précipitations moyennes par mois

Ensuite, on peut évidemment déclarer une ville :

MaVille : Ville

Voilà comment on pourrait initialiser cette ville

Afficher "Nom de la ville?" Saisir MaVille.Nom //idem pour l'altitude et le climat Afficher "Veuillez entrer successivement les températures moyennes sur les 12 mois" //on utilise une boucle pour remplir le tableau des températures Pour i de 1 jusqu'à 12 Faire Aff "mois ", i Saisir MaVille.Temp[i]

FinPour //idem pour les précipitations

Si on voulait afficher par exemple la température moyenne au mois de juillet de MaVille, on écrirait tout simplement :

Aff MaVille.Temp[7]

// vu que le tableau commence à 1, 7 est l'indice de juillet

III. Les tableaux d'enregistrements (ou tables)

Il arrive souvent que l’on veuille traiter non pas un seul enregistrement mais plusieurs. Par exemple, on veut pouvoir traiter un groupe de personne. On ne va donc pas créer autant de variables du type personne qu’il y a de personnes. On va créer un tableau regroupant toutes les personnes du groupe. Il s’agit alors d’un tableau d’enregistrements, autrement appelé « table ». Une table en algorithmique a beaucoup de points communs avec une table d’une base de donnée. Les colonnes sont appelées champs et les lignes enregistrements.

5

S. Laporte

Type structurés et enregistrements

DAIGL

// nombre de personnes du groupe

Exemple page suivante Const NP = 20

Type Structure personne nom: chaîne age: entier

FinStruct

Var groupe: tableau[1..NP] de personnes

Chaque élément du tableau est un enregistrement, contenant plusieurs variables de type différent. On accède à un enregistrement par son indice dans le tableau.

groupe[2] représente la deuxième personne du groupe groupe[2].nom représente le nom de la deuxième personne du groupe

nom

âge

nom des champs

1

2

3

4

5

indices du tableau

? Attention!

enregistrements

groupe.nom[3] n'est pas valide.

Pour accéder au nom de la troisième personne du tableau, il faut écrire groupe[3].nom

Une table comme champ de structure

Les tableaux d'enregistrements peuvent aussi être eux même servir de type dans un autre type structuré

Exemple Contexte : Dans un comité d'entreprise, on veut pouvoir connaître les enfants des employés et leur date de naissance (pour le petit cadeau!). On suppose que le nombre d'enfant maxi d'un employé est de 10.

Structure Enfant Nom : chaîne Prénom : chaîne Journaiss : entier Moisnaiss : entier Anneenaiss :entier FinStructure

Structure Employé Nom : chaîne Prénom : Chaîne … Nbenf : entier Progéniture : tableau[1..10] d'Enfant

//nombre d'enfants

Publicité

6

S. Laporte

FinStruct

Type structurés et enregistrements

DAIGL

Et évidemment, on pourrait déclarer un tableau d'Employé. Ce qui ferait des tableaux imbriqués les uns dans les autres…

Var TabEmp : tableau[1..MAX] d'Employé

Pour afficher par exemple les anniversaires de tous les enfants de l'employé d'indice i, il faudrait parcourir le tableau de ses enfants (avec un autre indice que i).

Si TabEmp[i].NbEnf ? 0 //on vérifie d'abord que l'employé a des enfants Alors

Pour j de 1 jusqu'à TabEmp[i].NbEnf Faire Aff TabEmp[i].Progéniture[j].Prénom Aff "anniversaire le ", TabEmp[i].Progéniture[j].journaiss, TabEmp[i].Progéniture[j].moisnaiss

FinPour Sinon Aff "l'employé ", TabEmp[i].Nom, " n'a pas d'enfant" FinSi

IV Les enregistrements comme paramètres Comme c'est le cas avec les tableaux, il est possible de passer un enregistrement en paramètre d'une fonction ou d'une procédure (on n'est pas obligé de passer tous les champs uns à uns, ce qui permet de diminuer le nombre de paramètres à passer). On peut aussi avoir un enregistrement comme valeur de retour d'une fonction

Exemple

Struct hms

heure : entier minute : entier seconde : entier

FinStruct

Remarque : Les types structures sont déclarées en global

Fonction nbsec(time : hms) : entier Var Début

nbsec : entier

nbsec ? time.heure* 3600 + time.minute * 60 + time.seconde Retourne nbsec

FinProcédure

Procédure converthms(E nbsec :entier S time : hms)

Début

time.heure ? nbsec DIV 3600 reste ? nbsec MOD 3600 time.minute ? reste DIV 60 time.seconde ? nbsec MOD 60

FinProcédure

Du coup, la procédure converthms n'a plus qu'un seul paramètre résultat et peut être transformée en fonction

7

S. Laporte

Type structurés et enregistrements

DAIGL

Fonction converthms(nbsec :entier) : hms Var

time : hms

Début

time.heure ? nbsec DIV 3600 reste ? nbsec MOD 3600 time.minute ? reste DIV 60 time.seconde ? nbsec MOD 60 retourne time

FinProcédure

Exemples d'appels

Appel de la fonction converthms :

Var duréesec : entier

duréeh : hms

Début Saisir duréesec duréeh ? converthms(duréesec) Aff "durée correspondante: ", durée.heure, "h ", durée.minute, "m ", durée.seconde, "s" Fin

Appel de la fonction nbsec dans une autre fonction durée :

Fonction durée (h1 : hms, h2: hms) : hms Var

d : hms sec : entier

Début

sec ? nbsec(h2) – nbsec(h1) d ? converthms(sec) retourne d

FinFonction

retourne converthms(nbsec(h2) – nbsec(h1))

Remarque : Lors de l'appel d'un sous-programme, un paramètre peut-être représenté par un ou plusieurs champ d'un enregistrement (tout comme on peut passer la valeur d'une seule case d'un tableau en paramètre)

8