• Aucun résultat trouvé

Algorithmique et Programmation

N/A
N/A
Protected

Academic year: 2021

Partager "Algorithmique et Programmation"

Copied!
18
0
0

Texte intégral

(1)

Algorithmique et Programmation

8h CM, 12h TD, 10h TP

1- Enregistrement

2- Algorithmes de recherche et de tri 3- Complexité algorithmique

4- Fichiers, gestion des erreurs

www.u-picardie.fr/~furst/algo_prog.php

(2)

Notions vue en S1 : - algorithme - variables

- type de donnée

- instructions, expressions - conditionnelles, boucles - tableau

- fonctions

Premier complément : les enregistrements - facilitent l'écriture des programmes

- permettent de représenter explicitement ce que décrivent les données

Enregistrement

(3)

Il est possible (en C et dans de nombreux langages) de définir un type ordonné en spécifiant explicitement ses valeurs :

Remarque : en C, les valeurs des énumérations sont des entiers.

Énumération

enum arc_en_ciel {rouge, orange, jaune, vert, bleu, indigo, magenta, violet};

arc_en_ciel coul <- bleu;

enum arc_en_ciel {rouge=27, orange, jaune=-4, vert, bleu, indigo, magenta, violet};

enum arc_en_ciel coul1 = violet, coul2 = coul1+2;

printf("%d",(int) coul2); // affiche 3

(4)

Types structurés : une valeur n’est pas atomique mais constituée d’autres valeurs

Exemple : type tableau, toutes les valeurs sont de même type

Attention : un type tableau est un type, un tableau est une valeur d’un type tableau.

En C, on peut déclarer un type tableau avec

typedef

Type de données structuré

typedef int montype[3];

typedef float truc[];

montype toto;

truc tab = {2.3,4.0};

entier montableau[300];

pour (i allant de 0 à montableau.longueur pas de 1) faire montableau[i] <- 0;

finpour

montableau[0] <- 7;

(5)

Les enregistrements permettent d’agréger des valeurs de types différents.

On déclare les types enregistrement en précisant leurs champs avec leurs types et identifiants :

Les enregistrements sont déclarés et initialisés comme les tableaux :

Enregistrement

enregistrement Personne chaine nom, prenom;

entier age;

finenregistrement

Personne p1;

p1.nom <- "Duchmol";

p1.prenom <- "Robert";

p1.age <- 32;

Personne p2 <- {"Tartempion", "Marcel", 54};

(6)

Enregistrement en C

struct Personne{

char *nom, *prenom;

int age;

};

struct Personne p1;

p1.nom = "Duchmol";

p1.prenom = "Robert";

p1.age = 32;

struct Personne p2 = {"Tartempion", "Marcel", 54};

En C, il faut toujours indiquer avant le nom du type enregistrement qu'il s'agit d'un type enregistrement, sauf si on utilise le mot-clé typedef .

typedef struct{

char *nom, *prenom;

int numero;

} Etudiant;

Etudiant e;

...

(7)

enregistrement Personne chaine nom, prenom;

entier age;

finenregistrement Personne p;

p.nom <- "Dupuis";

nom <- "Duchemin";

int age <- 34;

p.age <- 32;

enregistrement Etudiant chaine surnom, numero;

entier numero, age;

finenregistrement

Un identifiant de champ n’est visible que dans les enregistrements instances du type où il est défini.

Un identifiant de champ n’a donc aucun sens s’il n’est pas préfixé par l’identifiant d’un enregistrement :

Visibilité des champs

(8)

Les champs d’un type enregistrement peuvent être de tout type, y compris enregistrement.

Combinaison d'enregistrements

enum diplome {licence, master, doctorat};

enregistrement Inscription

entier annee; // année dans le diplome diplome dip;

entier dispense_assiduite;

finenregistrement

enregistrement Etudiant entier numero;

chaine nom;

Inscription inscrip;

finenregistrement

(9)

Il est possible qu’un type enregistrement contienne un champ typé par lui-même.

En C, il est nécessaire d’utiliser des pointeurs pour déclarer ce type d’enregistrement.

Enregistrement récursif

struct Personne{

int age;

char *nom;

struct Personne *pere, *mere;

};

struct Personne p1, p2, p3;

...

*p1.pere = p2;

p1.mere = &p3;

enregistrement Personne entier age;

chaine nom;

Personne pere, mere;

finenregistrement

(10)

Il est possible qu’un champ d’un type enregistrement soit de type tableau.

Enregistrements et tableaux

enregistrement Etudiant entier numero;

chaine nom;

Inscription inscrip;

réel notesSemestre[];

finenregistrement

Etudiant tab[200];

tab[0].nom <- "Dupont";

tab[0].notesSemestres[0] <- 14.5 ; ...

Il est possible de manipuler des tableaux d’enregistrements.

Attention : en C, un champ de type tableau dont la taille n'est pas fixée doit être

déclaré à la fin de l'enregistrement !

(11)

Un tableau à deux dimensions peut être vu comme un tableau de tableau.

Tableau multidimensionnel

caractère morpion[3][3];

morpion[1][1] <- 'o';

chaine we[2] <- {"samedi","dimanche"};

morpion

' o

' '

o ' morpion

' s '

' a '

' m '

' e '

' d '

' i ' we

' d '

' i '

' m '

' a '

' n '

' c '

' h '

' e '

(12)

Structurer les données facilite l’écriture des programmes et l’échange des données entre parties des programmes (fonctions).

Structures de données

annee : 1

dip : licence

dispense_assiduite : 0  numero : 2

 nom : "Dupont"

 inscrip :  

notesSemestre :

 numero : 3  nom : "Durand"

 inscrip :  

notesSemestre :

... ... ...

 n : 14  n : 12  n : 5   n : 18 annee : 1

dip : licence

dispense_assiduite : 0 enregistrement Note

entier n, coef;

finenregistrement

enregistrement Etudiant entier numero;

chaine nom;

Inscription inscrip;

Note notesSemestre[];

finenregistrement

 n :14

 coef :   n : 12

 coef :   n : 5

 coef :   n : 18  coef : 

(13)

En C, on peut déclarer un type enregistrement et le décrire plus tard :

En pratique, ça n’est utile que pour déclarer des types interdépendants.

Déclaration de type enregistrement en C

struct Etudiant; // déclaration incomplète ...

struct Etudiant{ // description du type int numero;

char *nom;

};

struct Oeuf;

struct Poule{

Oeuf aPondu;

};

struct Oeuf{

Poule ponduPar;

}

(14)

En langage C, affecter un enregistrement à une variable recopie toutes les valeurs des champs.

Affectation globale d'enregistrement

struct Etudiant{

int numero, annee;

char *nom;

};

struct Etudiant e1, e2;

...

e1 = e2; // équivalent à e1.numero = e2.numero;

// e1.annee = e2.annee;

// e1.nom = e2.nom;

(15)

Dans de nombreux langages, il est possible de donner des valeurs par défaut aux champs.

En C, c’est impossible, mais on peut définir un enregistrement par défaut.

Valeurs par défaut des champs

enregistrement Etudiant

entier numero, annee <- 1;

chaine nom;

finenregistrement

struct Etudiant{

int numero, annee;

char *nom;

}Etudiant_defaut={0,1,""};

struct Etudiant e = Etudiant_defaut;

e.numero = 23456;

e.nom = "Dupond";

Remarques :

- les valeurs servant à initialiser les champs doivent être des constantes

- il est possible de ne pas donner de nom au type (mais alors on ne peut

plus l’utiliser dans le reste du code)

(16)

Les enregistrements peuvent être transmis aux fonctions par valeur ou par référence :

Paramètre de type enregistrement

struct Etudiant{

int numero, annee;

char *nom;

};

// transmission par valeur, l’enregistrement est recopié int compare(struct Etudiant t1, struct Etudiant t2){

return t1.numero – t2.numero;

}

// transmission par référence

void changeNom(struct Etudiant *t, char *n){

(*t).nom = n; // ou t->nom = n ; }

(17)

Attention : au cas où on ne trouve pas l’étudiant, que renvoyer ?

Solution bancale : créer un enregistrement avec un champ bidon (par exemple un numéro négatif) et le renvoyer.

Valeur de retour de type enregistrement

enregistrement Etudiant entier numero, annee;

chaine nom;

finenregistrement

fonction avec retour Etudiant trouve(Etudiant t[], entier tSize, chaine n) entier indice <- -1;

entier i <- 0;

début

tantque (indice=-1 et i<tSize) faire si (t[i].nom = n) alors

indice <- i;

finsi

i <- i+1;

fintantque fin

Les enregistrements peuvent être retournés par les fonctions :

(18)

En C, il faut mieux renvoyer un pointeur sur l’enregistrement, et utiliser la valeur NULL

Retour de type enregistrement en C

struct Etudiant{

int numero, annee;

char *nom;

};

struct Etudiant* trouve(struct Etudiant t[], int tSize, char *n){

int indice = -1;

int i = 0;

while(indice==-1 && i<tSize){

if(t[i].nom == n) indice = i;

i++;

}

if(indice == -1) return NULL;

else return &t[indice];

}

Références

Documents relatifs

à une liste (obtenue après suppression de la première cellule de la liste d’origine)!. Si une liste liste n’est

Chapitre 4 : Listes chaînées Mise à

Chaîne formée, de gauche à droite, de la valeur!. des feuilles

[r]

[r]

Sinon, on parcourt l'arbre, afin de rechercher un nœud qui sera le père de l'élément que nous désirons

[r]

pour chaque sous-arbre sélectionné, le transformer pour qu'il vérifie la propriété du tas, sachant que tous ses sous-arbres vérifient