Exercices : 1 2 3 4 5
Exercice 1
Télécharger l’exercice exo1.c

- On inclue les bibliothèques utiles
1
2
3
| #include <stdio.h>
#include <stdlib.h>
|
- On définie la structure Chainon pour représenter un élément d’une liste chaînée
1
2
3
4
5
6
| typedef struct chainon_struct
{
int value; // Valeur stockée dans le chainon
struct chainon_struct* next; // Pointeur vers le prochain chainon
} Chainon;
|
- On crée la fonction qui crée un nouveau chainon avec la valeur ‘a’ et renvoie un pointeur vers celui-ci
1
2
3
4
5
6
7
8
9
10
11
12
| Chainon* creationChainon(int a){
Chainon* nouveau = malloc(sizeof(Chainon)); // Allocation mémoire pour un nouveau chainon
if (nouveau == NULL) // Vérification de l'échec d'allocation
{
exit(EXIT_FAILURE); // Quitter le programme en cas d'échec
}
nouveau->value = a; // Initialisation de la valeur du chainon
nouveau->next = NULL; // Le chainon est initialisé sans successeur
return nouveau; // Retourne un pointeur vers le nouveau chainon
}
|
- On crée la fonction pour insérer un chainon au début de la liste
1
2
3
4
5
6
7
8
9
10
11
12
| Chainon* insertDebut(Chainon* pliste, int a){
if (pliste == NULL) // Si la liste est vide
{
pliste = creationChainon(a); // Créer un nouveau chainon
} else {
Chainon* nouveau = creationChainon(a); // Créer un nouveau chainon
nouveau->next = pliste; // L'ancien premier élément devient le suivant du nouveau chainon
pliste = nouveau; // Le nouveau chainon devient le premier de la liste
}
return pliste; // Retourner la nouvelle tête de liste
}
|
- On crée la fonction pour insérer un chainon à la fin de la liste
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| Chainon* insertFin(Chainon* pliste, int a){
if (pliste == NULL) // Si la liste est vide
{
pliste = creationChainon(a); // Créer un nouveau chainon
} else {
Chainon* actual = pliste; // Commencer au début de la liste
while (actual->next != NULL) // Parcourir la liste jusqu'à la fin
{
actual = actual->next;
}
actual->next = creationChainon(a); // Ajouter le nouveau chainon à la fin
}
return pliste; // Retourner la tête de la liste
}
|
- On crée la fonction pour afficher la liste chainée
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| void afficheListe(Chainon* pliste){
if (pliste == NULL) // Si la liste est vide
{
printf("liste vide\n"); // Afficher un message
}
Chainon* actual = pliste; // Commencer au début de la liste
while (actual->next != NULL) // Parcourir la liste jusqu'à l'avant-dernier élément
{
printf("%d -> ", actual->value); // Afficher la valeur de chaque chainon
actual = actual->next;
}
printf("%d", actual->value); // Afficher la dernière valeur sans flèche
printf("\n");
}
|
- On crée la fonction pour lire un entier sécurisé depuis l’utilisateur
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| int better_scan(const char * message){
int ret_var = 0; // Variable pour capturer le résultat de scanf
int value = 1; // Initialisation de la variable à retourner
while (ret_var != 1) // Boucle jusqu'à obtenir une saisie valide
{
if (message != NULL)
{
printf("%s", message); // Afficher le message si non nul
}
ret_var = scanf("%d", &value); // Lecture de la valeur
while(getchar()!='\n'){} // Vider le buffer de saisie (sécurisation)
}
return value; // Retourner la valeur saisie
}
|
- On teste le tout dans la fonction principale
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| int main(){
Chainon* pliste = NULL; // Initialiser la liste vide
int nb = 0; // Variable de contrôle de la boucle
int i = 1; // Compteur pour les valeurs insérées
while (nb == 0) // Tant que l'utilisateur souhaite ajouter des éléments
{
pliste = insertFin(pliste, i); // Insérer la valeur i à la fin de la liste
afficheListe(pliste); // Afficher la liste actuelle
i = i * 2; // Doubler la valeur de i pour la prochaine insertion
nb = better_scan("Nombre suivant ? \n0 - oui \nautre - non\n"); // Demander à l'utilisateur s'il veut continuer
}
// On libére la mémoire allouée pour la liste
Chainon* actual = pliste;
while (pliste != NULL)
{
actual = pliste->next; // Sauvegarder le prochain chainon
free(pliste); // Libérer la mémoire du chainon actuel
pliste = actual; // Passer au chainon suivant
}
return 0; // Fin du programme
}
|
Exercice 2
Télécharger l’exercice exo2.c

- On utilise les fonctions et structures précédentes
1
2
3
4
5
|
#include <stdio.h>
#include <stdlib.h>
...
|
- On crée la fonction pour insérer un élément dans une liste triée
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| Chainon* InsertTrie(Chainon* pliste, int a) {
if ( pliste == NULL || a <= pliste->value) { // Si l'élément est plus petit ou égal à la première valeur
return insertDebut(pliste, a); // Insère au début de la liste
}
Chainon* borne1 = pliste; // Pointeur sur l'élément actuel
Chainon* borne2 = pliste->next; // Pointeur sur l'élément suivant
while (borne2 != NULL) { // Parcourt la liste jusqu'à trouver la bonne position pour insérer 'a'
if (borne1->value < a && a <= borne2->value) { // Si 'a' est compris entre les deux valeurs
Chainon* a_chainon = creationChainon(a); // Crée un nouveau chainon avec la valeur 'a'
a_chainon->next = borne2; // Le nouveau chainon pointe vers 'borne2'
borne1->next = a_chainon; // 'borne1' pointe maintenant vers le nouveau chainon
return pliste; // Retourne la tête de la liste
}
borne1 = borne2; // Passe la borne1 à l'élément suivant a chaque tour de bouvle
borne2 = borne2->next; // Passe la borne2 à l'élément suivant a chaque tour de boucle
}
return insertFin(pliste, a); // Si 'a' est plus grand que toutes les valeurs, insère à la fin
}
|
- On teste le tout dans la fonction principale
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| int main() {
Chainon* pliste = NULL; // Initialise la liste à vide
for (int i = 0; i < 20; i += 5) { // Insère des multiples de 5 dans la liste
pliste = insertFin(pliste, i); // Insère chaque élément à la fin
}
afficheListe(pliste); // Affiche la liste après insertion
pliste = InsertTrie(pliste, 2); // Insère 2 dans la liste
pliste = InsertTrie(pliste, 12); // Insère 12 dans la liste
pliste = InsertTrie(pliste, 22); // Insère 22 dans la liste
afficheListe(pliste); // Affiche la liste après les insertions triées
Chainon* actual = pliste;
while (pliste != NULL)
{
actual = pliste->next; // Sauvegarder le prochain chainon
free(pliste); // Libérer la mémoire du chainon actuel
pliste = actual; // Passer au chainon suivant
}
return 0; // Fin du programme
}
|
Exercice 3
Télécharger l’exercice exo3.c

- On utilise les fonctions et structures précédentes
1
2
3
4
5
| #include <stdio.h>
#include <stdlib.h>
#include <time.h>
...
|
- On crée la fonction pour supprimer la première occurrence d’un élément ‘a’ dans la liste
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| Chainon* SupprimerPremier(Chainon* pliste, int a){
if (pliste == NULL){
return pliste; // Liste vide
}
if (pliste->value == a){// Cas où le premier élément de la liste doit être supprimé
Chainon* suppr = pliste; // Stocke l'élément à supprimer
pliste = pliste->next; // Le suivant devient le premier élément
free(suppr); // Libère la mémoire
return pliste; // Retourne la nouvelle tête de liste
}
Chainon* actual = pliste;
Chainon* suppr = NULL;
while (actual->next != NULL){
if (actual->next->value == a){ // Trouve l'élément à supprimer
suppr = actual->next; // Stocke l'élément à supprimer
actual->next = actual->next->next; // Saute cet élément dans la liste
free(suppr); // Libère la mémoire
return pliste; // Retourne la tête de la liste
}
actual = actual->next; // Continue à parcourir la liste
}
return pliste; // Retourne la liste si l'élément n'a pas été trouvé
}
|
- On crée la fonction pour supprimer toutes les occurrences d’un élément ‘a’ dans la liste
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| Chainon* SupprimerTout(Chainon* pliste, int a){
if (pliste == NULL){
return pliste; // Liste vide
}
while (pliste != NULL && pliste->value == a){// Cas où le premier élément doit être supprimé (si c'est 'a')
Chainon* suppr = pliste;
pliste = pliste->next; // Le suivant devient le premier
free(suppr); // Libère la mémoire du chainon supprimé
}
Chainon* actual = pliste;
Chainon* suppr = NULL;
while (actual != NULL && actual->next != NULL){// Parcourt la liste à partir du deuxième élément
if (actual->next->value == a){ // Trouve l'élément à supprimer
suppr = actual->next;
actual->next = actual->next->next; // Saute l'élément dans la chaîne
free(suppr); // Libère la mémoire
} else {
actual = actual->next; // Passe au chainon suivant
}
}
return pliste; // Retourne la tête de la liste modifiée
}
|
- On teste le tout dans la fonction principale
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| int main(){
srand(time(NULL));
Chainon* pliste = NULL;
for (int i = 0; i < 10; i++){
pliste = insertFin(pliste, rand() % 6);
}
afficheListe(pliste);
pliste = SupprimerPremier(pliste, 2);
afficheListe(pliste);
pliste = SupprimerTout(pliste, 5);
afficheListe(pliste);
Chainon* actual = pliste;
while (pliste != NULL){
actual = pliste->next;
free(pliste);
pliste = actual;
}
return 0;
}
|
Exercice 4
Télécharger l’exercice exo4.c

- On utilise les fonctions et structures précédentes
1
2
3
4
5
6
| #include <stdio.h>
#include <stdlib.h>
#include <time.h>
...
|
- On crée la fonction pour inverser la liste en créant une nouvelle liste
1
2
3
4
5
6
7
8
9
10
11
| Chainon* Inverse(Chainon* pliste){
Chainon* newliste = NULL; // Nouvelle liste initialement vide
Chainon* actual = pliste; // Commence à parcourir la liste originale
while (actual != NULL){
newliste = insertDebut(newliste, actual->value); // Insère au début de la nouvelle liste
actual = actual->next; // Passe au chainon suivant
}
return newliste; // Retourne la nouvelle liste inversée
}
|
- On crée la fonction pour inverser la liste en modifiant les pointeurs directement sans passer par une liste intermédiaire
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| Chainon* Inverse2(Chainon* pliste){
if (pliste == NULL){
return NULL; // Retourne NULL si la liste est vide
}
Chainon* previous = pliste->next; // Pointeur sur le deuxième élément
Chainon* actual = pliste; // Pointeur sur le premier élément
Chainon* tmp = NULL; // Variable temporaire pour la manipulation des pointeurs
actual->next = NULL; // Le premier élément devient le dernier, donc son pointeur 'next' est NULL
while (previous != NULL){
tmp = previous->next; // Sauvegarde le prochain élément
previous->next = actual; // Inverse le pointeur du chainon actuel
actual = previous; // Avance le chainon actuel
previous = tmp; // Passe au chainon suivant
}
return actual; // Retourne la nouvelle tête de la liste inversée
}
|
- On test le tout dans la fonction principale sans oublier de free les différentes listes a la fin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| int main(){
srand(time(NULL));
Chainon* pliste = NULL;
for (int i = 0; i < 10; i++){
pliste = insertFin(pliste, rand() % 6);
}
afficheListe(pliste);
Chainon* pliste2 = Inverse(pliste);
afficheListe(pliste2);
pliste2 = Inverse2(pliste2);
afficheListe(pliste2);
Chainon* actual = pliste;
while (pliste != NULL){
actual = pliste->next;
free(pliste);
pliste = actual;
}
actual = pliste2;
while (pliste2 != NULL){
actual = pliste2->next;
free(pliste2);
pliste2 = actual;
}
return 0;
}
|
Exercice 5
Télécharger l’exercice exo5.c

- On definie les différentes structure/definitions/fonctions utiles pour le programme
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define Nb_notes 10
typedef struct etudiant_struct {
char nom[50];
char prenom[50];
int groupe;
int notes[Nb_notes];
} Etudiant;
typedef struct chainon_struct {
Etudiant etudiant;
struct chainon_struct* next;
} Chainon;
int better_scan(const char * message){
int ret_var = 0;
int value = 1;
while (ret_var != 1)
{
if (message != NULL)
{
printf("%s", message);
}
ret_var = scanf("%d", &value);
while(getchar()!='\n'){} // Ligne facultative de sécurisation
}
return value;
}
|
- On crée la fonction pour créer un nouvel étudiant
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| Etudiant creerEtudiant() {
Etudiant etudiant;
printf("Nom: ");
if (fgets(etudiant.nom, 50, stdin) == NULL){
exit(EXIT_FAILURE);
}
etudiant.nom[strlen(etudiant.nom)-1] = '\0';
printf("Prenom: ");
if (fgets(etudiant.prenom, 50, stdin) == NULL){
exit(EXIT_FAILURE);
}
etudiant.prenom[strlen(etudiant.prenom)-1] = '\0';
printf("Groupe: ");
etudiant.groupe = better_scan("Saisir numero grp :\n");
for (int i = 0; i < Nb_notes; i++) {
etudiant.notes[i] = rand() % 21; // Notes entre 0 et 20
}
return etudiant;
}
|
- On crée la fonction pour ajouter un étudiant à la fin de la liste
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| void saisirEtudiant(Chainon** lst) { //on utilise un double pointeur pour ne pas avoir besoin de retourner la liste
Chainon* nouveau = (Chainon*)malloc(sizeof(Chainon));
if (nouveau == NULL) {
printf("Erreur d'allocation mémoire.\n");
exit(EXIT_FAILURE);
}
nouveau->etudiant = creerEtudiant();
nouveau->next = NULL;
if (*lst == NULL) {
*lst = nouveau;
} else {
Chainon* tmp = *lst;
while (tmp->next != NULL) {
tmp = tmp->next;
}
tmp->next = nouveau;
}
}
|
- On crée la fonction pour afficher les étudiants par groupe
1
2
3
4
5
6
7
8
9
10
| void listeParGroupe(Chainon* lst, int groupe) {
Chainon* tmp = lst;
while (tmp != NULL) {
if (tmp->etudiant.groupe == groupe) {
printf("%s %s\n", tmp->etudiant.nom, tmp->etudiant.prenom);
}
tmp = tmp->next;
}
}
|
- On crée la fonction pour calculer la moyenne d’un tableau de notes
1
2
3
4
5
6
7
8
| float moyTab(int* tab) {
float somme = 0;
for (int i = 0; i < Nb_notes; i++) {
somme += tab[i];
}
return somme / Nb_notes;
}
|
- On crée la fonction pour trouver un étudiant par nom et prénom
1
2
3
4
5
6
7
8
9
10
11
| Chainon* trouveEtudiant(char* nom, char* prenom, Chainon* lst) {
Chainon* tmp = lst;
while (tmp != NULL) {
if (strcmp(tmp->etudiant.nom, nom) == 0 && strcmp(tmp->etudiant.prenom, prenom) == 0) {
return tmp;
}
tmp = tmp->next;
}
return NULL;
}
|
- On crée la fonction pour calculer la moyenne d’un étudiant spécifique
1
2
3
4
5
6
7
8
9
| void moyenneEtudiant(Chainon* lst, char* nom, char* prenom) {
Chainon* etudiant = trouveEtudiant(nom, prenom, lst);
if (etudiant) {
printf("Moyenne de %s %s: %f\n", nom, prenom, moyTab(etudiant->etudiant.notes));
} else {
printf("Erreur: aucun étudiant avec le nom %s %s trouvé.\n", nom, prenom);
}
}
|
- On crée la fonction pour calculer la moyenne de toute la promotion
1
2
3
4
5
6
7
8
9
10
11
12
13
| float moyennePromotion(Chainon* lst) {
float somme = 0;
int count = 0;
Chainon* tmp = lst;
while (tmp != NULL) {
somme += moyTab(tmp->etudiant.notes);
count++;
tmp = tmp->next;
}
return count ? somme / count : 0;
}
|
- On crée la fonction pour afficher l’étudiant avec la plus mauvaise moyenne
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| void etudiantPireMoyenne(Chainon* lst) {
if (lst == NULL) {
printf("Pas d'étudiants dans la liste.\n");
return;
}
Chainon* tmp = lst;
Chainon* pire = lst;
float pireMoyenne = moyTab(tmp->etudiant.notes);
while (tmp != NULL) { //calcul classique de minimum
float moyenneActuelle = moyTab(tmp->etudiant.notes);
if (moyenneActuelle < pireMoyenne) {
pire = tmp;
pireMoyenne = moyenneActuelle;
}
tmp = tmp->next;
}
printf("L'étudiant avec la plus mauvaise moyenne est %s %s avec %f de moyenne.\n", pire->etudiant.nom, pire->etudiant.prenom, pireMoyenne);
}
|
- On crée le main pour choisir ce que l’on veut faire
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
| int main() {
srand(time(NULL));
Chainon* etudiant_plist = NULL;
int choix, groupe;
char nom[50], prenom[50];
do {
printf("\nMenu:\n");
printf("1. Saisir un nouvel étudiant\n");
printf("2. Afficher les étudiants par groupe\n");
printf("3. Calculer la moyenne d'un étudiant\n");
printf("4. Calculer la moyenne de la promotion\n");
printf("5. Afficher l'étudiant avec la plus mauvaise moyenne\n");
printf("6. Quitter\n");
printf("Votre choix: ");
choix = better_scan("Votre choix: ");
switch (choix) {
case 1:
saisirEtudiant(&etudiant_plist);
break;
case 2:
groupe = better_scan("Entrez le numéro du groupe: ");
listeParGroupe(etudiant_plist, groupe);
break;
case 3:
printf("Entrez le nom de l'étudiant: ");
if (fgets(nom, 50, stdin) == NULL){
exit(EXIT_FAILURE);
}
nom[strlen(nom)-1] = '\0';
printf("Entrez le prénom de l'étudiant: ");
if (fgets(prenom, 50, stdin) == NULL){
exit(EXIT_FAILURE);
}
prenom[strlen(prenom)-1] = '\0';
moyenneEtudiant(etudiant_plist, nom, prenom);
break;
case 4:
printf("Moyenne de la promotion: %f\n", moyennePromotion(etudiant_plist));
break;
case 5:
etudiantPireMoyenne(etudiant_plist);
break;
case 6:
printf("Salem !\n");
break;
default:
printf("Choix invalide!\n");
break;
}
} while (choix != 6);
Chainon* actual = etudiant_plist; //On oublie pas de free la memoire
while (etudiant_plist != NULL){
actual = etudiant_plist->next;
free(etudiant_plist);
etudiant_plist = actual;
}
return 0;
}
|
Exercices : 1 2 3 4 5
Le contenu de cet article est la propriété exclusive de son auteur.