IFT-2000: Structures de données Plan de cours Théorie du contrat Types abstraits Dominic Genest, 2009.

Slides:



Advertisements
Présentations similaires
Introduction Langage très répandu Noyau Linux VLC … Des avantages indéniables mais aussi des contraintes ! Ceci nest quun rapide tour.
Advertisements

Erratum C Surcharge For(int x=0; … 2.
Rappels C.
GEF 243B Programmation informatique appliquée
C.
Paramètres et pointeurs
Structures et unions types énumérés Qu'est-ce qu'une structure
Chap. 1 Structures séquentielles : listes linéaires
FLSI602 Génie Informatique et Réseaux
Points importants de la semaine Les fonctions. La portée. La passage par copie. Les tableaux.
La fonction alloue un bloc de taille size. Il faut indiquer la taille du bloc que lon veut allouer. Le premier exemple: #include void main()
TRAITEMENT DE STRUCTURES
IFT-2000: Structures de Données Listes chaînées Dominic Genest, 2009.
Les Classes les structures en C (struct) regroupent des variables : structuration de l'analyse mais problèmes de cohérence problèmes de sécurité d'accès.
Quest-ce quune classe dallocation? Une classe dallocation détermine la portée et la durée de vie dun objet ou dune fonction.
Leçon 2 : Surcharge des opérateurs IUP 2 Génie Informatique Méthode et Outils pour la Programmation Françoise Greffier Université de Franche-Comté.
Les pointeurs Enormément utilisé en C/C++ ! Pourquoi? A quoi ça sert?
HistoriqueHistorique Langage C++, parution du livre Bjarne Stroustrup Normalisation ANSI.
Les pointeurs Modes d’adressage de variables. Définition d’un pointeur. Opérateurs de base. Opérations élémentaires. Pointeurs et tableaux. Pointeurs et.
IFT-2000: Structures de données
IFT-2000: Structures de données Les graphes Dominic Genest, 2009.
Structures de données IFT-2000
Structures de données IFT Abder Alikacem Espace de nommage Département d’informatique et de génie logiciel Édition Septembre 2009.
Structures de données IFT-2000
Structures de données IFT Abder Alikacem Gestion des exceptions Département dinformatique et de génie logiciel Édition Septembre 2009.
Structures de données IFT-2000
Un langage de programmation hybride
8PRO100 Éléments de programmation Les types composés.
COURS DE PROGRAMMATION ORIENTEE OBJET :
Leçon 1 : notion dobjet IUP Génie Informatique Besançon Méthode et Outils pour la Programmation Françoise Greffier Université de Franche-Comté.
IFT-2000: Structures de données Piles et files Dominic Genest, 2009.
Structures de données IFT-2000
Structures de données IFT-2000 Abder Alikacem La récursivité Semaine 5 Département dinformatique et de génie logiciel Édition Septembre 2009.
Structures de données IFT Abder Alikacem Gestion des exceptions Module 2 Département dinformatique et de génie logiciel Édition Septembre 2009.
IFT-2000: Structures de données Éléments techniques avancés du C et du C++ Dominic Genest, 2009.
Structures de données IFT-2000
Structures de données IFT-2000 Abder Alikacem Retour sur les listes ordonnées Département dinformatique et de génie logiciel Édition Septembre 2009.
Plan cours La notion de pointeur et d’adresse mémoire.
Structures de données IFT-2000 Abder Alikacem La récursivité Département d’informatique et de génie logiciel Édition Septembre 2009.
Structures de données IFT-2000
Structures de données IFT-2000
Structures de données IFT-2000 Abder Alikacem Introduction Semaine 1 Département d’informatique et de génie logiciel Édition Septembre 2009.
Structures de données IFT-10541
Le langage C Structures de données
2.1 - Historique Chapitre 2 : Introduction au langage C++
Le langage C Rappel Pointeurs & Allocation de mémoire.
Ch. PAUL - Piles et Files à l'aide de listes chainées
LES PILES ET FILES.
Les Pointeurs et les Tableaux Statiques et Tableaux Dynamiques
LIFI-Java 2004 Séance du Mercredi 22 sept. Cours 3.
La notion de type revisitée en POO
et quelques rappels sur certains éléments du langage C
Cours 61 6 La sécurité, Portée, Visibilité Programmer avec sécurité.
GESTION ET TRAITEMENT DES ERREURS
1 Structures des données. 2  Le tableau permettait de désigner sous un seul nom un ensemble de valeurs de même type, chacune d'entre elles étant repérée.
Master 1 SIGLIS Java Lecteur Stéphane Tallard Les erreurs communes en Java.
Tutorat en bio-informatique
HistoriqueHistorique Langage C++, parution du livre Bjarne Stroustrup Normalisation ANSI.
Les types composés Les enregistrements.
Les surcharges d'opérateurs
ISBN Chapitre 10 L'implémentation des sous- programmes.
Classe 1 CSI2572 Autres modificateurs de déclaration de variables: & volatile & register & static & auto & extern & const volatile Indique au compilateur.
Conception de Programmes - IUT de Paris - 1ère année Conception de Programmes Objectifs et organisation du cours Introduction à la P.O.O.
Conception de Programmes - IUT de Paris - 1ère année Quelques éléments du langage C++ Les références La surcharge de fonctions Les fonctions «
8PRO107 Éléments de programmation Les adresses et les pointeurs.
Structures de données IFT-2000 Abder Alikacem Laboratoire #1 Département d’informatique et de génie logiciel Édition Septembre 2009.
Exception Handling "Unfortunately, it's almost accepted practice to ignore error conditions, as if we're in a state of denial about errors." Bruce Eckel.
Conception de Programmes - IUT de Paris - 1ère année Les classes Introduction Déclaration d’une classe Utilisation d’une classe Définition des.
Transcription de la présentation:

IFT-2000: Structures de données Plan de cours Théorie du contrat Types abstraits Dominic Genest, 2009

Dominic Genest Disponibilité sur rendez-vous (quand vous voulez) Site web du cours: http://w3.ift.ulaval.ca/~dogen19/ift Remise des TP par l’Intranet Pixel Pour toute question sur la matière ou sur les travaux: Pour communiquer directement avec moi par MSN: ift- (ne m’écrivez pas de courriel à cette adresse-ci, il sera perdu)ift- Les cours en direct ont lieu là: Dominic Genest, 2009

Le plan de cours Pour cette session d’été 2009, un problème technique m’empêche de saisir les dates d’examens sur l’intranet Pixel. Elles ont tout de même été fixées: – Examen #1 (33%): Le dimanche 7 juin 2009 de 13h30 à 16h30 – Examen #2 (33%): Le dimanche 12 juillet 2009 de 13h30 à 16h30 Dominic Genest, 2009

Travaux à remettre Cinq travaux à remettre aux dates suivantes: – TP #1 (10%): 29 mai h00 – Série d’exercices #1 (2%): 1 er juin h00 – TP #2 (10%): 19 juin h00 – Série d’exercices #2 (2%): 29 juin h00 – TP #3 (10%): 6 juillet h00 Dominic Genest, 2009

Théorie du contrat Non-respect de la théorie du contrat // Nombres.h #define MAX 1000 typedef struct { float t[MAX]; int nb; } Nombres; // SuperProg.c #include ‘’Nombres.h’’ int main() { Nombres mes_nombres; mes_nombres.nb=3; mes_nombres.t[0]=33.12f; mes_nombres.t[1]=2537.6f; mes_nombres.t[1]=302.5f; return 0; } Respect de la théorie du contrat // Nombres.h typedef enum { OK,ERREUR } CodeErreur; typedef struct { float t[MAX]; int nb; } Nombres; CodeErreur initNombres(Nombres *nombres); CodeErreur ajoutNombres(Nombres *nombres, float nouveau_nombre); float rechercherNombres(const Nombres *nombres, int indice, CodeErreur *err); CodeErreur detruireNombres(Nombres *nombres); // Nombres.c CodeErreur initNombres(Nombres *nombres) { nombres->nb=0; return OK; } CodeErreur ajoutNombres(Nombres *nombres, float nouveau_nombre) { if(nombres->nb==MAX) return ERREUR; nombres->t[nombres- >nb++)=nouveau_nombre; return OK; } float rechercherNombres(const Nombres *nombres, int indice, CodeErreur *err) { float *x; if(indice>=nombres->nb) { *err=ERREUR; return 0.0f; } *err=OK; return nombres->t[indice]; } CodeErreur detruireNombres(Nombres *nombres) { return OK; } // SuperProg.c #include ‘’Nombres.h’’ int main() { Nombres mes_nombres; initNombres(&mes_nombres); ajoutNombres(&mes_nombres,33.12f); ajoutNombres(&mes_nombres,2537.6f); ajoutNombres(&mes_nombres,302.5f); return 0; } Dominic Genest, 2009

On change l’implémentation Code originel // Nombres.h typedef enum { OK,ERREUR } CodeErreur; typedef struct { float t[MAX]; int nb; } Nombres; CodeErreur initNombres(Nombres *nombres); CodeErreur ajoutNombres(Nombres *nombres, float nouveau_nombre); float rechercherNombres(const Nombres *nombres, int indice, CodeErreur *err); CodeErreur detruireNombres(Nombres *nombres); // Nombres.c CodeErreur initNombres(Nombres *nombres) { nombres->nb=0; return OK; } CodeErreur ajoutNombres(Nombres *nombres, float nouveau_nombre) { if(nombres->nb==MAX) return ERREUR; nombres->t[nombres- >nb++)=nouveau_nombre; return OK; } float rechercherNombres(const Nombres *nombres, int indice, CodeErreur *err) { if(indice>=nombres->nb) { *err=ERREUR; return 0.0f; } *err=OK; return nombres->t[indice]; } CodeErreur detruireNombres(Nombres *nombres) { return OK; } // SuperProg.c #include ‘’Nombres.h’’ int main() { Nombres mes_nombres; initNombres(&mes_nombres); ajoutNombres(&mes_nombres,33.12f ); ajoutNombres(&mes_nombres, f); ajoutNombres(&mes_nombres,302.5f ); return 0; } Code changé pour un tableau dynamique // Nombres.h typedef enum { OK,ERREUR } CodeErreur; typedef struct { float *t; int nb; } Nombres; CodeErreur initNombres(Nombres *nombres); CodeErreur ajoutNombres(Nombres *nombres, float nouveau_nombre); float rechercherNombres(const Nombres *nombres, int indice, CodeErreur *err); CodeErreur detruireNombres(Nombres *nombres); // Nombres.c CodeErreur initNombres(Nombres *nombres) { nombres->nb=0; nombres->t=0; return OK; } CodeErreur ajoutNombres(Nombres *nombres, float nouveau_nombre) { float *nouveau_t = realloc(nombres- >t,sizeof(float)*(nombres->nb+1)); if(!nouveau_t) return ERREUR; nombres->t=nouveau_t; nombres->t[nombres- >nb++)=nouveau_nombre; return OK; } float rechercherNombres(const Nombres *nombres, int indice, CodeErreur *err) { if(indice>=nombres->nb) { *err=ERREUR; return 0.0f; } *err=OK; return nombres->t[indice]; } CodeErreur detruireNombres(Nombres *nombres) { free(nombres->t); return OK; } // SuperProg.c #include ‘’Nombres.h’’ int main() { Nombres mes_nombres; initNombres(&mes_nombres); ajoutNombres(&mes_nombres,33.12f ); ajoutNombres(&mes_nombres, f); ajoutNombres(&mes_nombres,302.5f ); return 0; } Dominic Genest, 2009

Avantages de la notion de type abstrait Non-respect de la théorie du contrat On modifie sauvagement les données dans structures à tous les endroits où on a besoin des structures. On considère que tous les membres de la structure sont accessibles. Ça semble plus facile à faire pour un débutant. Un changement de conception d’une structure devient impossible dès que le logiciel prend de l’envergure. Respect de la théorie du contrat L’idée est de préparer le logiciel à un changement radical du contenu de la structure. On passe obligatoirement par des fonctions pour accéder aux membres structures. On ne fait jamais de supposition sur l’existence de tel membre. Plus difficile à réaliser pour un débutant. Ça facilite les changements de conception de structures. Dominic Genest, 2009

Théorie du contrat Cela est peu convaincant avec un si petit exemple, mais lorsque le programme devient un peu plus grand, cela a un impact majeur sur la réussite d’un projet. On doit toujours favoriser la simplicité et la durée de vie du code qui utilise les structures, et non pas du code qui implémente ces structures. Dominic Genest, 2009

Codes d’erreurs À quoi bon retourner un code d’erreur quand la fonction retourne toujours le même? CodeErreur initNombres(Nombres *nombres) { nombres->nb=0; return OK; } C’est pour préparer un éventuel changement pour une implémentation où on pourrait imaginer qu’une erreur survienne (un manque de mémoire par exemple) à l’initialisation. Dominic Genest, 2009

Fonction de destruction À quoi bon faire une fonction de destruction vide? CodeErreur detruireNombres(Nombres *nombres) { return OK; } C’est pour préparer une éventuelle implémentation où on aurait vraiment quelque chose à faire (libérer de la mémoire, sans doute) lorsque l’objet n’est plus utilisé. Dominic Genest, 2009

Théorie du contrat en C++ Le langage C++ permet de faire en sorte que le compilateur interdisse l’utilisation de certains membres de structures, par le mot-clé « private ». Aussi, les fonctions peuvent être placées à l’intérieur-même de la structure, évitant ainsi d’avoir à passer un paramètre supplémentaire à chaque fonction. Dominic Genest, 2009

En C++ // Nombres.h struct Nombres { public: // Ceci permet l’accès aux membres suivants depuis l’extérieur Nombres(); // On appelle cette fonction membre spéciale un // « constructeur » void ajout(float nouveau_nombre); float rechercher(int indice) const; ~Nombres(); // On appelle cette fonction-ci un « destructeur » private: // Ceci interdit l’accès aux membres suivants depuis l’extérieur // Seul le code à l’intérieur des fonctions membres ont le droit // d’y accéder. float *t; int nb; }; // Nombres.c Nombres::Nombres() { nb=0; t=0; } void Nombres::ajout (float nouveau_nombre) { float *nouveau_t = realloc(t,sizeof(float)*(nb+1)); if(!nouveau_t) throw -1; t=nouveau_t; t[nb++]=nouveau_nombre; } float Nombres::rechercher (int indice) const { if(indice>=nb) throw -1; return t[indice]; } CodeErreur detruireNombres(Nombres *nombres) { free(nombres->t); return OK; } // SuperProg.c #include ‘’Nombres.h’’ #include // Pour « cout » et « endl », qui remplacent « printf » // en C++ using namespace std;// Pour éviter d’avoir à toujours écrire « std::cout » // plutôt que juste « cout ». int main() { try { // Si jamais un « throw » est effectué dans l’un ou l’autre // des appels suivants, on saute immédiatement au bloc // « catch » Nombres mes_nombres; // Ceci appelle // automatiquement le constructeur Nombres::Nombres() mes_nombres.ajout(33.12f); mes_nombres.ajout (2537.6f); mes_nombres.ajout (302.5f); } // L’accolade fermante termine la portée de la variable // « mes_nombres », ce qui appelle automatiquement // son destructeur Nombres::~Nombres catch(int code_erreur) { cout << ‘’Erreur #’’ << code_erreur << ‘’!’’ << endl; return -1; } return 0; } Dominic Genest, 2009

Les types abstraits Quand on développe une structure, on doit le considérer comme un « type abstrait », c’est-à-dire dont la spécification ne dépend pas de l’implémentation. Pour établir cette spécification (qui risque moins de changer que l’implémentation), il faut avoir recours à une documentation complète de chacune des fonctions qui permettent de manipuler les objets du type en question. La meilleure façon de procéder est d’employer une convention sur la façon de documenter les fonctions. La convention de documentation la plus utilisée à l’heure actuelle est sans doute celle employée par l’utilitaire Doxygen Doxygen permet de générer automatiquement, à partir du code, une documentation dans un format pratique (le plus souvent html). Dominic Genest, 2009

Principales différences entre C++ et C en ce qui concerne le cours C malloc(sizeof(float)*25) free(x) realloc(x,sizeof(float)*25); typedef struct { // […] } MaStruct; void fonction(MaStruct *m,float x); Aucun équivalent pour « private: », il faut user de discipline. float f(float a, int x, int *err) { if(x<a) { *err=PROBLEME; return 0.0f; } // […] } int x; for(x=0;x<2;x++) C++ new float[25] delete x ou delete[] x Pas d’équivalent pour « realloc » struct MaStruct { void fonction(float x); }; Possibilité de rendre des membres privés à l’aide de « private: » float f(float a, int x) { if(x<a) throw PROBLEME; // […] } for(int x=0;x<2;x++) Dominic Genest, 2009

Les pointeurs Il s’agit en réalité tout simplement d’un nombre emmagasiné sur 4 octets (comme un « int »). Le fait qu’une variable soit déclarée du type pointeur indique au compilateur que le nombre que contiendra cette variable devra être interprété comme une adresse-mémoire. Le « type pointé », c’est-à-dire le type indiqué en avant de l’étoile lors de la déclaration, sert à donner au compilateur une indication sur le nombre d’octets à lire ou écrire en mémoire à partir de l’adresse-mémoire indiquée par le contenu du pointeur. – Par exemple, l’instruction « *x=25 » écrira 4 octets si x a été déclaré comme un « int* » tandis qu’elle écrira deux octets si x a été déclaré comme un « short* ». Ce type pointé sert aussi à donner au compilateur une indication sur le décalage d’adresse-mémoire à effectuer lors de l’utilisation de l’opérateur []. – Par exemple, l’instruction « x[3]=25 » écrira à 12 octets plus loin que « x[0]=25 » si x a été déclaré comme un « int* » tandis qu’elle écrira à seulement 6 octets plus loin si x a été déclaré comme un « short* ». Ce type pointé sert aussi à l’arithmétique effectué sur les pointeurs à l’aide des opérateurs + et -. En effet, les opérateurs + et – appliqués aux pointeurs donnent des décalages en « nombre d’éléments » et non pas en « nombre d’octets », tout comme l’opérateur []. – Par exemple, l’instruction « *(x+3)=25 » a toujours exactement le même effet que « x[3]=25 », et les décalages effectués sont multipliés par sizeof(type pointé) de la même façon qu’avec [], en respect du type pointé. Dominic Genest, 2009