Ename: inverse layout: true class: center, middle, inverse --- # Inès de Courchelle ## Les tableaux de structures  --- layout: false # Rappel - Les tris ## Les lents | algo | pire | meilleur | moyen | | -- | -- | -- | -- | | Sélection | Ο(N²) | Ο(N²) | Ο(N²) | | Bulles | Ο(N²) | Ο(N) | Ο(N²) | | Insertion | Ο(N²) | Ο(N) | Ο(N²) |
--- # Rappel - Les tris ## Les rapides | algo | pire | meilleur | moyen | | -- | -- | -- | -- | | Rapide | Ο(N²) | Ο(n log(n)) | Ο(n log(n)) | | Fusion | Ο(n log(n) | Ο(n log(n)) | Ο(n log(n)) |
--- # Today ## Objectifs - Utiliser les chaînes de caractères sans complexes - Référencer des données plus complexes - Manipuler des données multi-type - Chercher des solutions dans la doc - Lier des données
--- # Les chaînes de caractères ## Définition - Un tableau de caractères qui permet de stocker des lettres - Plus généralement, c'est une variable mémoire permettant de stocker du texte ## Représentation
--- # Les chaînes de caractères ## Exemple
--- # ASCII ## On peut stocker des entiers dedans | 0 | 1 | 2 | 3 | 4 | 5 | 6 | | - | - | - | - | - | - | - | | 65 | 66 | 79 | 78 | 45 | 52 | 50 | ## Si on affiche - %d .arrow[] on affichera l'entier - %c .arrow[] on affichera la correspondance avec un caractère ## De la doc -
Comment ça marche
-
wikibooks
--- # Affichage ## Un caractère
--- # La fin ## Le caractère \0 - Une chaine de caractères se termine toujours par 0 - Le caractère \0 permet de dire que c'est la fin du tableau ## Illustration Le mot coucou doit être stocké sur 7 cases (la N°6) ! | 0 | 1 | 2 | 3 | 4 | 5 | 6 | | --- | ---- | --- | --- | --- | --- | --- | | C | o | u | c | o | u | \0 | --- # Utilisation ## La manuelle ```c chaine[0] = 'C'; chaine[1] = 'O'; chaine[2] = 'U'; chaine[3] = 'C'; chaine[4] = 'O'; chaine[5] = 'U'; chaine[6] = '\0'; ```
--- # Utilisation ## L'automatique La taille du tableau est automatiquement calculé ```c #include
#include
#include
int main() { char chaine[] = "COUCOU"; printf("%s", chaine); printf("La taille de la chaîne est : %ld \n", strlen(chaine)); return 0; } ``` ## Attention Pour pouvoir utiliser la fonctionnalité .under[strlen], il faut le include string.h --- # Récupération ## Les symboles - Pour récupérer une lettre .arrow[] %c - Pour récupérer une chaîne .arrow[] %s - (Rappel) Pour récupérer une saisie utilisateur .arrow[] scanf ## Illustration ```c char nom[100]; printf("Qui es tu ? \n"); scanf("%s",nom); ``` #### Remarques - Il faut définir la taille de la chaîne - Il n'y a pas besoin du & pour une chaine de caractères dans un scanf #### Et pourquoi ? --- # Chaînes + Pointeurs ## En C .pull-left[ ### Avec Pointeur ```c char* chaine; chaine = malloc (sizeof(char)*100); printf("une chaine : : \n"); scanf("%s",chaine); free(chaine); ``` ] .pull-right[ ### Sans Pointeur ```c char chaine[100]; printf("une chaine : : \n"); scanf("%s",chaine); ``` ] .underR[Attention :] - Il ne faut pas oublier la taille de la chaîne de caractères - Sans pointeur : dans la définition - Dans les 2 cas, il n'y a pas besoins du & dans le scanf --- # Chaines ## Statiques VS Dynamique #### J'ai le droit ```c char* monNom; monNom="toto"; ``` #### Je n'ai pas le droit ```c char monNom[5]; monNom="toto"; ``` --- # Chaines ## Statiques VS Dynamique
--- # Manipulation de String ## La bibliothèque ```c #include
/* les classiques */ #include
/* les classiques */ #include
/* la petite nouvelle */ int main (){ return 0; } ``` ## Des fonctions - strlen .arrow[] avoir la taille d'une chaîne - strcpy .arrow[] copier une chaîne dans une autre - strcat .arrow[] concaténer 2 chaînes ensemble --- # Manipulation de String ## Illustration #### Avoir la taille d'une chaine ``` char* monNom; monNom="ines"; size_t tailleNom; tailleNom=strlen(monNom); printf("%ld \n",tailleNom); ``` #### size_t - C'est un format en c comme char, int, float, double ... - C'est comme un long int (un entier long) - Pour afficher un entier long : %ld --- # Manipulation de String ## Illustration : Avoir la taille d'une chaine
--- # # Realloc ## Avantage des pointeurs - On peut .under[redéfinir] la chaine de caratéres à tout moment, sans passer par un scanf - .under[attention] : il ne faut pas oublier le free à la fin ## Mais Comment ? ```c realloc(monPointeur,nouvelleTaille*sizeof(typeDuPointeur)); ``` --- # Realloc ## Mais Comment ? ```c int* mesNotes; mesNotes = malloc (sizeof(int)*2); for (int i=0;i<2;i++){ printf("pour la note %d tu as eu : \n",i); scanf("%d",&mesNotes[i]); } /* REALLOCATION DYNAMIQUE */ mesNotes=realloc(mesNotes,3*sizeof(int)); mesNotes[2]=42; for (int i=0;i<3;i++){ printf("pour la note %d tu as eu : %d \n",i,mesNotes[i]); } free(mesNotes); ``` ## Problèmes - Allocation pour 2 notes ! - Solution on peut rajouter de l'espace ! - L'instruction .under[realloc] --- # Realloc ## VAR
--- # Realloc ## VAR
--- # Afficher le manuel - C ## Comment ? Dans un terminal, il suffit de taper : ```bash man 3
``` ## Pourquoi ? - Pour savoir comment fonctionne une commande - Quelle(s) bibliothèque(s) une fonction a besoin pour s'exécuter - Parce que ! --- # Afficher le manuel - C ## Exemple
--- # Les tableaux de structures ## Objectifs - Référencer des données plus complexes - Manipuler des données multi-type - Lier des données
--- # Qu'est ce qu'une structure ? ## Définition - Regrouper plusieurs variables de types différents au sein d’une même variable qui a un sens “métier” - Exemples : - nombre complexe - étudiant - joueur - ... - Composer d'un ou plusieurs champs ## Objectifs - Définir un nouveau type de donnée - Obtenir un type générique composés d'un ensemble de données ## Où déclare t-on une structure ? Dans le .h --- # Structure ## Représentation
## En C ```c struct Nom_Structure { type_champ1 Nom_Champ1; type_champ2 Nom_Champ2; type_champ3 Nom_Champ3; }; ``` --- # Structure ## Une voiture .pull-left[
] .pull-right[ ### Qu'est-ce qui caractérise une voiture ? - Une vitesse max - Un poids - ... ] ## Une musique .pull-left[
]
.pull-right[ ### Qu'est-ce qui caractérise une music ? - un titre - une durée - ... ] --- # Structure ## Exemple 1 .pull-left[
] .pull-right[ ```c struct voiture { double vitesse; double poids; }; typedef struct voiture voiture; ``` ]
## Exemple 2 .pull-left[
] .pull-right[ ```c struct music { char* titre; double duree; }; typedef struct music music; ``` ] --- # Structure ## Le programme ```c music m1, m2; /* declaration des variables musics */ voiture v; /* declaration de variable voiture */ m1.titre="Dig a pony"; m1.duree=234; m2.titre="One afer 909"; m2.duree=174; v.vitesse=130; v.poids=800; printf("Je suis le morceau de music %s et ma durée est de %.2f sec\n",m1.titre,m1.duree); printf("Je suis le morceau de music %s et ma durée est de %.2f sec\n",m2.titre,m2.duree); printf("Je suis une voiture qui roule à %fd et dont le poids est %.2f kg \n",v.vitesse,v.poids); ``` ## Les décimales - La précision des virgules à afficher peut être donnée dans le printf - %f .arrow[] toutes les décimales seront affichées - %.3f .arrow[] les 3 premiers chiffres après la virgule - %.2f .arrow[] les 2 premiers chiffres après la virgule - ... --- # Structure ## Exemple
--- # Structure ## En compilation séparée (Rappel) #### La définition La définition du << squelette >> est à réaliser dans un << .h >> #### L'utilisation L'utilisation (création de variable, manipulation ...) dans les << .c >> ## Exemple - Pour l'exemple précédent il faut tout couper ! - on peut même se faire plaisir en faisant une procédure d'affichage
--- # Structure ## Procédure d'affichage ```c void afficherMusic(music m){ printf("Je suis le morceau de music %s et ma durée est de %.2f sec\n",m.titre,m.duree); } void afficherVoiture(voiture v){ printf("Je suis une voiture qui roule à %.2f et dont le poids est %.2f kg \n",v.vitesse,v.poids); } ``` --- # Structure ## Séparation
--- # Structure ## VAR
--- # Qu'est ce qu'un tableau ? ## Définition (Rappel) Ensemble de variables de même type, de même nom et caractérisées par un indice (ou index) ## En C (Rappel) #### Statique ```c /* Déclaration */ int monTab[100]; /* Affectation */ for (int i=0;i<100;i++){ tab[i]=i; } ``` --- # Qu'est ce qu'un tableau ? ## Définition (Rappel) Ensemble de variables de même type, de même nom et caractérisées par un indice (ou index) ## En C (Rappel) #### Dynamique ```c /* Déclaration */ int* p_tab; p_tab=NULL; p_tab = malloc(100 *sizeof(int)); /* Affectation */ for (int i=0;i<100;i++){ tab[i]=i; } /* Libération */ free(p_tab); p_tab=NULL; ``` --- # La donnée ## Problématiques ? - Plusieurs types - Liens entre les données - ...
.under[Que voyons nous apparaître comme données ?] --- # Exemple ## Les données - Une classe - Un nom, un prénom ... - Des éléves - Un niveau
#### Comment traduire cela en C ? --- # Des tableaux de structures ## On pose - Un tableau est un ensemble du même type de données - Une structure est un type de données défini par l’utilisateur ## La fusion - La déclaration d’un tableau de structures est la même que celle d’un tableau de types de données - Le type du tableau sera le type de la structure
--- # En C ## Le code ```c struct Nom_Structure { type_champ1 Nom_Champ1; type_champ2 Nom_Champ2; }; typedef struct Nom_Structure Nom_Structure; Nom_Structure monTableauDeStructs[3]; ```
--- # Illustration ## Des éléves
## Un tableau d'élèves
--- # L'école ## Objectifs - Lier les étudiants à des classes - Modèliser votre système d'information ## Comment ? - AVEC UN PAPIER ET UN STYLO - Avec des schèmas - Avec des tableaux à plusieurs dimensions
--- # L'école ## Ce que l'on veut - Un Élève appartient à un niveau - Une classe possède au plus 30 élèves ## Proposition - Un élève est : un nom + un prénom + un niveau + un numéro étudiant - Une classe est : un nom + un tableau d'élève + une taille d'étudiant --- # L'école ## Un élève .pull-left[
] .pull-right[ ```c struct Eleve { char* nom; char* prenom; int niveau; int numero; }; typedef struct Eleve Eleve; ``` ]
## Exemple .pull-left[ Archie Andrews - 1994 - 22 741
] .pull-right[ ```c Eleve e1; e1.nom1="Andrews" e1.prenom1="Archie" e1.niveau=1 e1.numero=22741 ``` ] --- # L'école ## Une classe .c1[ ```c Eleve e1; e1.nom="Andrews"; e1.prenom="Archie"; e1.niveau=1; e1.numero=22741; ``` ] .c2[ ```c Eleve e2; e2.nom="Blossom"; e2.prenom="Cheryl"; e2.niveau=1; e2.numero=22845; ``` ] .c3[ ```c Eleve e3; e3.nom="Jones"; e3.prenom="Jughead"; e3.niveau=1; e3.numero=22845; ``` ] .pull-left[
] .pull-right[ ```c struct Classe { char* nom; Eleve mesEleves[30]; int taille; }; typedef struct Classe Classe; ``` ] --- # La classe ## En C .pull-left[ ```c struct Classe { char nom [100]; Eleve mesEleves[30]; int taille; }; typedef struct Classe Classe; ``` ] .pull-right[ ```c uneClasse sY; sY.nom="seniorYear"; sY.taille=3; sY.mesEleves[0]=e1; sY.mesEleves[1]=e2; sY.mesEleves[2]=e3; ``` ]
## En schema
--- # Affichage ## Faire une procédure pour les élèves .pull-left[ ```c void afficherEleve(Eleve e){ printf("------ETUDIANT-------- \n"); printf("nom : %s \n",e.nom); printf("prenom : %s \n",e.prenom); printf("niveau : %d \n",e.niveau); printf("numero : %d\n",e.numero); } ``` ] .pull-right[
]
## Faire une procédure pour la classe .pull-left[ ```c void afficherClasse(Classe c){ printf("------ma classe-------- \n"); printf("nom classe : %s \n",c.nom); printf("%d eleves \n",c.taille); for(int i=0;i
--- # Le code ## Riverdale .pull-left[ #### riverdale.h ```c struct Classe { char* nom; Eleve mesEleves[30]; int taille; }; typedef struct Classe Classe; struct Eleve { char* nom; char* prenom; int niveau; int numero; }; typedef struct Eleve Eleve; void afficherEleve(Eleve e); void afficherClasse(Classe c); ``` ] .pull-right[ #### riverdale.c ```c void afficherEleve(Eleve e){ printf("------ETUDIANT-------- \n"); printf("nom : %s \n",e.nom); printf("prenom : %s \n",e.prenom); printf("niveau : %d \n",e.niveau); printf("numero : %d\n",e.numero); } void afficherClasse(Classe c){ printf("------ma classe-------- \n"); printf("nom classe : %s \n",c.nom); printf("%d eleves \n",c.taille); for(int i=0;i
--- # Exemple complet ## La var
--- # La version dynamique ## Lets go Nous désirons réaliser une version avec allocation dynamique. ## Objectifs - Les chaînes de caractères seront des pointeurs - Les élèves seront des pointeurs - La classe aura un tableau d'élèves dynamiques --- # Les élèves ## Représentation
## Exemple
--- # Les élèves ## En C ```c Eleve* e1; e1= malloc(sizeof(Eleve)*1); e1->nom="Andrews"; e1->prenom="Archie"; e1->niveau=1; e1->numero=22741; ``` ## La structure
--- # La classe ## En C ```c struct Classe { char* nom; Eleve* mesEleves; int taille; }; typedef struct Classe Classe; ``` ## La structure
--- # Classe + étudiants
.underR[Attention] les étudiants ne sont pas des pointeurs dans la structure Classe --- # Exemple complet ## La var
--- # Bilan de compétences ## La gestion des caractères - Manipulation différentes pour char et char* - Utilisation de fonctions pré-définies dans string.h ## Les structures - Tableau de structure statique - Tableau de structure dynamique