INGE2/INGE3 S3/S5 Robin FERCOQ 2013-2014 Organisation des données Structures de stockage 1
Organisation des données Structures de stockage I Données et traitements Méthodes de conception de programmes 2
I / Données et traitements Système Informatique : Stockage / Transmission / Traitement d'informations Données : Descriptions ou représentations d'informations Plusieurs niveaux de représentation : Utilisateur humain qui donne du sens aux choses Données structurées représentant des ''objets'' ou des ''collections d'objets'' Données élémentaires caractérisant chaque objet Binaire (représentation machine des données) 3
Bonjour Zorg le guerrier! Une bonne hache pour 15 pièces? Informations présentées à l'utilisateur Messages / Images / Animations / Sons joueur "Luc" 0 "magicien" perso "Zorg" 1 "guérisseur" classe 2 2 "guerrier" fortune 12 Types composés Tableaux / Structures 'L' 'u' 12-2427 Types scalaires fondamentaux Caractères / Entiers / Flottants / Pointeurs -2.5214 3.2178 6.5789 5.7894 3.9000 2.1036-3.2181-4.7411 3.7877 9.7865 6.5414 1.6546-2.521423 7.354846e3 01101110 11110100 00000001 01000000 10111000 10000010 10010100 Représentation binaire (niveau machine) 4
I / Données et traitements! Toutes les méthodes de conception distinguent Traitements : les actions, ordres du programme Données : ce qui est modifié par les actions, nombres ou symboles représentant des informations réelles ou virtuelles Le Modèle dans la méthode MVC articule ce binôme Données 10 notes Traitements saisie utilisateur 10 notes déterminer maximum maximum afficher maximum 5
I / Données et traitements! Selon la nature et la complexité du programme le rapport entre données et traitements évolue L'interface utilisateur (Vue) dissocie 1087 01440 string.h strlen strcpy strcmp strcat strdup strstr apparence des informations pour l'utilisateur représentation interne des données (codages) Des algorithmes efficaces pour traiter certains problèmes se basent sur des organisations particulières des données On utilise ou on développe des bibliothèques : on compose des structures de plus haut niveau avec des structures de niveau plus élémentaire. Les données se dotent d'interfaces standardisées pour ne plus avoir à manipuler les types de départ 6
I / Données et traitements! Autre problème : il y a 2 contextes de stockage Mémoires vives : RAMs Contenu des variables du programme en cours d'exécution (données traitées) Rapide (<1ns) mais volatile Mémoires de masse : disques durs, clés USB Fichiers et systèmes de fichiers Archivage, persistance des données Trop lent et pas assez souple pour servir directement de support de traitement pour un programme : on ne déclare pas une variable dans un fichier, les pointeurs alloués en RAM ne sont pas utilisables 7
I / Données et traitements Evolution du rapport données/traitement Logique de flux Entrée/Sortie (Input/Output stdio) Données initiales entrées (saisie ou fichier) Traitements Données résultat sorties (affichage ou fichier) 8
I / Données et traitements Evolution du rapport données/traitement Exemple : chiffres nombre en toutes lettres 689,95 entrée (saisie) Traitements Six cent quatre-vingt-neuf euros et quatre-vingt-quinze centimes sortie (impression chèque) 9
I / Données et traitements Evolution du rapport données/traitement Exemple : commandes ''filtres'' du système Unix M;Alphonse;1932;Martin F;Béatrice;1964;Guibert F;Charlotte;1988;Le Goff M;Jean Emmanuel;1999;Dupuis entrée (fichier liste.txt) cut -d ';' -f2,4 <liste.txt >out.txt Traitements Alphonse;Martin Béatrice;Guibert Charlotte;Le Goff Jean Emmanuel;Dupuis sortie (fichier out.txt) 10
I / Données et traitements Evolution du rapport données/traitement Algorithmes complexes : données intermédiaires Données initiales fichier en entrée Données intermédiaires Traitements Données résultat fichier en sortie 11
I / Données et traitements Evolution du rapport données/traitement Exemple : reconnaissance de caractères fichier image Traitements "research" fichier texte 12
I / Données et traitements Evolution du rapport données/traitement Exemple : compilation source exécutable } x = a - b/c + d*e; return 5*a + 20*x + 750; fichier source : main.c gcc main.c -o calculs + * a / b d Traitements e c langage machine + constantes fichier exécutable : calculs (unix) ou calculs.exe (windows) 13
I / Données et traitements Evolution du rapport données/traitement Modèle "application" : on travaille sur un document Données à modifier Traitements 14
! I / Données et traitements Evolution du rapport données/traitement Modèle "application" : on travaille sur un document charger tout mode "r" Données archivées entrées Données à modifier Traitements mode "w" sauver tout fichier(s) document Persistance clavier souris Vue écran sorties document monté en mémoire vive Programme en cours d'exécution apparence des données pour l'utilisateur Interface utilisateur IHM 15
i I / Données et traitements Evolution du rapport données/traitement Architecture Client/Serveur : site web dynamique synchro requêtes mode "r" scripts coté serveur réponses mode "w" fichiers serveur de données Persistance : Base de Données clavier souris requêtes scripts coté client réponses serveur web Serveur site web : données partielles Vue écran navigateur web apparence Pages web consultées dans le navigateur 16
I / Méthodes de conception! On passe d'une problématique d'implémentation pour un traitement de données "homogènes" Traitement central du CDC Problème central Sous-problèmes Analyse fonctionnelle descendante T1 Sous-sous-problèmes Sous-sous-sous-problèmes T2 T2.1 T2.2 T2.1.1 T2.1.2 T3 T2.3 T3.1 T3.2 17
I / Méthodes de conception exemple illustratif d'analyse descendante pour un traitement compliqué (analyse d'image) 18
! I / Méthodes de conception à une problématique d'organisation et d'assemblage d'ensembles "hétérogènes" de données ajout vol aéroport modif. vol avions passagers id billet nom num. prénom corresp. adresse date vols pistes navig. pilotes mécan. embarquements hotes. données hétérogènes mais cohérentes : organisées et structurées change pilote annonce retard autoriser décollage etc 19
I / Méthodes de conception! En résumé on évolue de Une conception centrée sur les traitements Décomposition complexe élémentaire Vers une conception centrée sur les données, nature (types), relations, protocoles d'accès Composition éléments ensembles L'analyse fonctionnelle descendante reste valable pour aborder des traitements complexes Certains choix sur l'organisation des données restent encore guidés par l'efficacité des traitements associés On associe étroitement structures et traitements pour obtenir des "objets" munis de "comportements" 20
Organisation des données Structures de stockage II Types de données 21
II / Types de données! Les données représentent les informations d'objets (réels ou virtuels) qui apparaissent souvent comme des ensembles d'éléments de même nature : partageant les mêmes attributs ayant des valeurs spécifiques pour chaque élément faisant l'objet d'actions ou traitements similaires Exemples : Ensemble Voiture Attributs : immatr. / proprio. / marque / couleur Actions : fabriquer / rouler / tourner Ensemble Etudiant Attributs : nom / prénom / note(s) / taille Actions : inscrire / appeler / évaluer 22
II / Types de données! En info. un tel ensemble est un type de donnée Un élément particulier de cet ensemble est appelé une variable ou instance de ce type Exemple : type Voiture Instance : ma première voiture Instance : la Clio immatriculée RT-187-LA Instance : la Batmobile 23
II / Types de données Les types prédéfinis du C ( scalaires ) correspondent à des types "techniques" pour données élémentaires. Bien que de même type float, des notes et des tailles ne doivent pas se retrouver confondus float notes_et_tailles[400]; // Pour 200 élèves??? 12.50 1.78 18.85 1.63 13.00 2.53 0 1 2 3 4 5 1.87 7.25 0.63 1.72 6 7 8 9 Les types élémentaires prédéfinis ne permettent pas de décider des bons regroupements pour la conception : pas de sémantique associée 24
II / Types de données! 2 approches fondamentales de composition de types tableau collection de données de même type Elements énumérables par boucle, accès direct et efficace au rang i Déclarer/allouer un tableau permet de gérer une collection d'instances de même type, souvent groupées selon une même intention Exemple : t_voiture * mon_parking[500]; struct collection de données de types hétérogènes "Elements" = champs ou attributs de la struct Accessibles seulement par le nom des champs Définir une struct amène un nouveau type Exemple : typedef struct voiture {} t_voiture; 25
II / Types de données Exemple simplifié, on gère une promo d'étudiants : on suppose 200 étudiants (nb. fixe pour l'instant) on doit stocker leur noms, prénoms, notes, tailles Une problématique qui revient souvent : Plusieurs tableaux ( de types distincts )? Tableau de structs ou de pointeurs sur structs? 26
II / Types de données promo.h #define NB_ETUDIANTS 200 Plusieurs tableaux de types distincts main.c #include "promo.h" int main() { // équivalent à char promo_noms[200][50]; char promo_noms[nb_etudiants][50]; // équivalent à char promo_prenoms[200][50]; char promo_prenoms[nb_etudiants][50]; // pour simplifier : une seule note par étudiant float promo_notes[nb_etudiants]; // pour optimiser les amphis float promo_tailles[nb_etudiants]; 27
II / Types de données Plusieurs tableaux de types distincts promo_noms 0 Martin promo_prenoms 0 Adèle promo_notes promo_tailles 0 12.8 0 1.87 1 Dubois 1 Stéphane 1 17.5 1 1.64 2 Legrand 2 Laurent 2 7.4 2 1.73 3 Georges 3 1.5 3 1.82 3 Morin 4 Garnier 4 Alice 4 11.7 4 1.68 198 Dubois 198 Emilie 198 18.1 198 1.61 199 Lefebvre 199 Pierre 199 11.4 199 1.79 28
II / Types de données Plusieurs tableaux de types distincts promo_noms promo_prenoms promo_notes promo_tailles Martin Adèle 12.8 1.87 Dubois Stéphane 17.5 1.64 Legrand Laurent 7.4 1.73 Morin Georges 1.5 1.82 Garnier Alice 11.7 1.68 Dubois Emilie 18.1 1.61 Lefebvre Pierre 11.4 1.79 Ce genre de regroupement est souvent mauvais : - Problèmes de maintient de cohérence (tris ) - La relation entre Martin, Dubois, Morin, Dubois est superficielle 29 - On ne peut gérer un étudiant sans avoir toute la promo
! II / Types de données Grouper autrement Martin Adèle 12.8 1.87 Dubois Stéphane 17.5 1.64 Legrand Laurent 7.4 1.73 Morin Georges 1.5 1.82 Garnier Alice 11.7 1.68 Dubois Emilie 18.1 1.61 Lefebvre Pierre 11.4 1.79 Le regroupement naturel commence par mettre ensemble les données d'un même étudiant 30
! II / Types de données Grouper autrement Martin Dubois Legrand Morin Adèle 12.8 1.87 Stéphane 17.5 1.64 Laurent 7.4 1.73 Georges 1.5 1.82 Garnier Alice 11.7 1.68 Dubois Emilie 18.1 1.61 Lefebvre Pierre 11.4 1.79 Le regroupement naturel commence par mettre ensemble les données d'un même étudiant 31
! II / Types de données Tableau de structs promo 0 Martin Adèle 12.8 1.87 1 Dubois Stéphane 17.5 1.64 2 Legrand Laurent 7.4 1.73 3 Morin Georges 1.5 1.82 4 Garnier Alice 11.7 1.68 198 Dubois 199 Lefebvre Emilie 18.1 1.61 Pierre 11.4 1.79 promo[198].note promo[198] t_etudiant Le regroupement naturel commence par mettre ensemble les données d'un même étudiant en définissant un type struct 32
! II / Types de données etudiant.h typedef struct etudiant { char nom[50]; char prenom[50]; float note; float taille; } t_etudiant; Tableau de structs main.c #include "etudiant.h" #include "promo.h" int main() { // equivalent à t_etudiant promo[200]; t_etudiant promo[nb_etudiants]; 33
II / Types de données promo Martin 0 Dubois 1 12.8 Morin 3 198 Garnier Dubois Alice Emilie 17.5 Laurent Georges Tableau de pointeurs sur structs 1.87 Stéphane Legrand 2 4 Adèle 11.7 1.73 1.82 1.68 18.1 1.64 7.4 1.5! 1.61 promo[198]->note *promo[198] t_etudiant 199 Lefebvre Pierre 11.4 1.79 promo[198] t_etudiant * Il est souvent préférable de gérer les collections de structs par pointeurs Les pointeurs jouent un rôle de référence vers chaque instance 34
II / Types de données etudiant.h typedef struct etudiant { } t_etudiant;! Tableau de pointeurs sur structs t_etudiant *etudiant_creer(); main.c #include "etudiant.h" #include "promo.h" int main() { int i; t_etudiant * promo[nb_etudiants]; for (i=0; i<nb_etudiants; i++) // création : utilise un malloc promo[i]=etudiant_creer(); 35
II / Types de données! Pointeurs et allocation Les pointeurs sont un exemple de métadonnées Les métadonnées sont des données permettant de trouver ou d'organiser d'autres données Paramètres et retours des sous-programmes : privilégier les passages par adresse plutôt que par valeur pour l'efficacité pas de copies Utilisation systématique de pointeurs sur des instances obtenues par allocation : favorise une autonomie des données référencées par rapport aux "conteneurs" et aux allers-retours des fcts. 36
! II / Types de données promo_alpha Martin Adèle Dubois 12.8 Stéphane Legrand Morin Garnier Dubois Tris Lefebvre Emilie Pierre 7.4 1.5 11.7 promo_grands 17.5 Laurent Georges Alice 1.87 1.82 1.64 1.73 Sélections 1.68 major 18.1 11.4 1.61 1.79 Instances uniques Pointeurs et collections de pointeurs sur structs : - Les mêmes objets peuvent être référencés dans plusieurs collections sans être dupliqués cohérence. 37 - Manipulation de pointeurs léger.
II / Types de données! Compléments sur les structs La déclaration classique de struct confond La déclaration de la struct et de son contenu La définition d'un type synonyme etudiant.h typedef struct etudiant { char nom[50]; char prenom[50]; float note; float taille; } t_etudiant; 38
II / Types de données Compléments sur les structs typedef pratique mais pas obligatoire etudiant.h etudiant.h typedef struct etudiant { char nom[50]; char prenom[50]; float note; float taille; } t_etudiant; struct etudiant { char nom[50]; char prenom[50]; float note; float taille; }; main.c main.c #include "etudiant.h" #include "etudiant.h" int main() { t_etudiant *major; int main() { struct etudiant *major; 39
II / Types de données Compléments sur les structs struct et typedef en 2 étapes etudiant.h struct etudiant { char nom[50]; char prenom[50]; float note; float taille; }; typedef struct etudiant t_etudiant; main.c #include "etudiant.h" int main() { t_etudiant *major; 40
II / Types de données Compléments sur les structs type struct utilisable avant déclaration contenu etudiant.h typedef struct etudiant t_etudiant; struct etudiant { char nom[50]; char prenom[50]; float note; float taille; }; main.c #include "etudiant.h" int main() { t_etudiant *major; 41
II / Types de données Compléments sur les structs type struct utilisable avant déclaration contenu #include "etudiant.h" typedef struct maillon t_maillon; struct maillon { t_etudiant *data; t_maillon *suiv; }; typedef t_maillon * t_liste_etu; main.c #include "liste_etu.h" liste_etu.h int main() { t_liste_etu promo; 42
II / Types de données Compléments sur les structs : structs dans structs /// etudiant.h typedef struct etudiant_ { char nom[50] OU char *nom; char prenom[50] OU char *prenom; // t_date date_naissance; t_date date_admission; t_cursus *majeure; t_modele3d *avatar; } t_etudiant; 43
II / Types de données Compléments sur les structs : structs dans structs /// date.h typedef struct date { } t_date; /// adresse.h typedef struct adresse { } t_adresse; /// identite.h typedef struct identite { char nom[50]; char prenom[50]; t_date date_naissance; t_adresse lieu_naissance; t_adresse lieu_residence; } t_identite; /// admission.h typedef struct admission { t_date date_depot, date_admission; t_diplome **liste_diplomes; } t_admission; /// etudiant.h typedef struct etudiant { t_identite *id; OU t_identite id;? t_admission dossier_admission; t_evaluations *liste_eval; t_modele3d *avatar; } t_etudiant; 44
Organisation des données Structures de stockage III Modularisation, abstraction Interface et implémentation 45
III / Modularisation La modularisation d'un programme a pour but son découpage en composants indépendants, et si possible de petite taille. Si tout le monde s'accorde à dire que cette approche est indispensable pour produire du logiciel de qualité, sa mise en œuvre soulève des problèmes variés et fait encore l'objet de controverses. Différents styles, non nécessairement compatibles, ont vu le jour Extrait de : Méthodologie de la programmation en C A. Braquelaire DUNOD 46
III / Modularisation On considérera qu'un programme est modulaire lorsqu'il est éclaté en composants, les modules, satisfaisant ces cinq objectifs : Lisibilité Maintenabilité Portabilité Extensibilité Réutilisabilité Extrait de Méthodologie de la programmation en C A. Braquelaire DUNOD 47
III / Modularisation!! Nous retiendrons l'approche module = type d'objet qui est à la base des méthodologies "orientées objet" Le C n'est pas un langage orienté objet mais des langages comme le C++ ou Java dérivent d'une "approche objet" déjà possible en C Un module sera défini à partir d'un type composé (généralement un type struct) représentatif d'un ensemble d'éléments partageant les mêmes attributs - avec valeurs spécifiques des comportements ou traitements similaires Exemple type point pour faire de la géométrie chaque point a des attributs x et y de val. spécifique tout point peut être créé, détruit, dessiné, translaté 48
III / Modularisation!! Un module est constitué par l'association type/traitements 1/ Définition du type comme collection d'attributs Exemple typedef struct point { float x; float y; } t_point; 2/ Définition d'un ensemble de sous-programmes permettant de "manipuler" des instances de ce type Exemple t_point * point_creer(float x, float y) void point_dessiner(t_point *p, t_vue *v) float point_distance(t_point *p1, t_point *p2) 49
III / Modularisation!! Un principe essentiel de modularité est la séparation entre Interface Accessible par les développeurs/utilisateurs du module : ils accéderont toujours aux fonctionnalités du module par l'interface. On dit que l'interface est publique. Implémentation La manière technique de représenter les données et les algorithmes permettant de mettre en œuvre concrètement les traitements demandés. En "orienté objet" on considère que ce genre de "détails" doivent rester privés. Les utilisateurs n'ont pas à mettre les mains dessus. 50
!! III / Modularisation En C un tel module se décompose en 2 fichiers : Interface Déclarée dans un fichier en-tête :.h Vo ir p ro je t - Déclaration du type - Prototypes des sous-programmes publiques m od ul e_ po in t Implémentation Définie dans un fichier source :.c - Définitions des sous-programmes publiques 51
III / Modularisation Un module C comporte aussi parfois : Vo ir! pr oj et m od ul Interface e_ po Déclarée dans un fichier en-tête :.h in t_ - Constantes et globales associées au type de riv - Déclaration du type e - Prototypes des sous-programmes publiques Implémentation Définie dans un fichier source :.c - Instanciation et initialisation des globales - Définitions des sous-programmes auxiliaires privés - Définitions des sous-programmes publiques 52
III / Modularisation!! Lorsque ces principes sont respectés et qu'il est effectivement possible de travailler avec des objets du type défini par le module, sans jamais accéder directement aux données internes mais en s'appuyant sur un répertoire standardisé de comportements ( aux conventions d'appels bien définis ) on obtient un type abstrait de donnée : abstract data type On fait "abstraction" de l'implémentation en disposant de (et en utilisant exclusivement) l'interface. L'implémentation peut être changée sans remettre en cause le code utilisateur du module. Exemple : le type FILE et ses appels associées fopen, fclose, feof, fprintf, fscanf, fgets, fflush 53
III / Modularisation! code utilisateur d'objets du type t_machin tout passe par l'interface du module machin Pas d'accès direct à la représentation interne créer malloc appels à l'interface détruire lire free int char * écrire spécifiques return ob->x = ob->x param int int char char Définit le type abstrait de donnée Interface : stable int char Implémentation : interchangeable 54
III / Modularisation! type étudiant Interface Implémentation Interface Implémentation Interface type identité Implémentation type date Exemple d'interaction entre plusieurs modules d'après Méthodologie de la programmation en C 55