← algo
TP · Programmation C2 · Prof. Dr. Amrani Ayoub

TP Programmation C2

Cinq travaux pratiques autour des pointeurs, des fonctions, des structures et de la récursivité. Chaque énoncé est accompagné de son en-tête de fonction, d'une animation et de la solution complète.

Exercice 1
★★

Gestion de températures

Tableau dynamique de réels et moyenne

Énoncé

Une station météo enregistre les températures d'une journée. Demander n, allouer dynamiquement un tableau de réels, saisir les températures, puis calculer et afficher la moyenne.
float moyenne(float *tab, int n);

Tableau alloué sur le tas (°C)
18
0
22
1
19
2
25
3
21
4
somme
0
moyenne
01 / 12
malloc réserve n cases ; somme ← 0
float moyenne(float *tab, int n)
1float moyenne(float *tab, int n) {
2 float somme = 0;
3 for (int i = 0; i < n; i++)
4 somme += tab[i];
5 return somme / n;
6}
À retenir

Le tableau est réservé sur le tas car n n'est connu qu'à l'exécution. Ne pas oublier free(tab) à la fin.

Exercice 2
★★

Gestion de stock

Min & max retournés par pointeurs

Énoncé

Analyser les quantités de produits en stock : une fonction qui prend un tableau d'entiers et sa taille, et retourne le minimum et le maximum à l'aide de pointeurs. Le programme principal initialise le tableau, appelle la fonction et affiche les résultats.
void analyse(int *tab, int n, int *min, int *max);

Quantités en stock
45
12
78
33
60
8
*min
45
*max
45
01 / 07
*min et *max ← tab[0] = 45
void analyse(…, int *min, int *max)
1void analyse(int *tab, int n,
2 int *min, int *max) {
3 *min = tab[0];
4 *max = tab[0];
5 for (int i = 1; i < n; i++) {
6 if (tab[i] < *min) *min = tab[i];
7 if (tab[i] > *max) *max = tab[i];
8 }
9}

La fonction est void mais renvoie deux résultats — par les pointeurs min et max. C'est l'équivalent C du passage VAR.

À retenir

Une fonction C ne renvoie qu'une valeur avec return. Pour en ressortir deux, on les écrit à travers des pointeurs passés par l'appelant.

Exercice 3
★★

Système de notes

Ajouter un bonus via un pointeur

Énoncé

Une université ajoute un bonus aux notes. Écrire une fonction qui prend un pointeur vers une note et lui ajoute 2 points, puis l'appliquer à chaque élément d'un tableau de notes et afficher les nouvelles notes.
void bonus(float *note);

Tableau de notes (modifié en place)
8
[0]
14
[1]
11
[2]
17
[3]
6
[4]
01 / 11
Notes initiales — on va appliquer bonus() à chacune
void bonus(float *note)
1void bonus(float *note) {
2 *note += 2;
3}
4// for (i) bonus(&notes[i]);

Sans le pointeur, bonus ne modifierait qu'une copie : le tableau resterait inchangé. C'est exactement le même principe que swap.

À retenir

En passant &notes[i], la fonction modifie directement la case du tableau. Sans pointeur, l'addition serait perdue au retour.

Exercice 4
★★

Gestion d'étudiants

Tableau de structures et moyenne

Énoncé

Stocker les informations d'étudiants : créer une structure (nom, note), déclarer un tableau de 3 étudiants, saisir leurs informations, puis calculer et afficher la moyenne des notes.
float moyenne(struct Etudiant *tab, int n);

struct Etudiant tab[3]
tab[0]
Ali
14
tab[1]
Sara
17
tab[2]
Karim
11
somme
0
moyenne
01 / 05
somme ← 0 ; on parcourt le tableau de structures
float moyenne(struct Etudiant *tab, int n)
1struct Etudiant { char nom[50]; float note; };
2
3float moyenne(struct Etudiant *tab, int n) {
4 float somme = 0;
5 for (int i = 0; i < n; i++)
6 somme += tab[i].note;
7 return somme / n;
8}

On accède au champ d'un élément du tableau par tab[i].note. (Via un pointeur isolé on écriraitp->note.)

À retenir

Une structure regroupe des champs de types différents. On accède au champ d'un élément du tableau avec tab[i].note.

Exercice 5
★★★

Analyse récursive des notes

Somme récursive puis moyenne

Énoncé

Calculer la somme des notes de façon récursive : une fonction qui prend un tableau d'étudiants et sa taille et retourne la somme des notes ; puis en déduire et afficher la moyenne.
float sommeNotes(struct Etudiant *tab, int n);

Pile d'appels de sommeNotes
sommeNotes(3)
somme
01 / 08
sommeNotes(3) = tab[2].note + sommeNotes(2)
float sommeNotes(struct Etudiant *tab, int n)
1float sommeNotes(struct Etudiant *tab, int n) {
2 if (n == 0) return 0; // cas de base
3 return tab[n-1].note
4 + sommeNotes(tab, n-1); // appel récursif
5}

On traite le dernier étudiant puis on délègue le reste à l'appel récursif. Le cas de base n == 0 arrête la descente.

À retenir

La récursion décompose le tableau : on additionne la dernière note et on relance sur les n-1 précédentes, jusqu'à n == 0 qui renvoie 0.