TP4 Correction
TP4 Correction
TP4 Correction
Préambule
À compléter dans le cours :
double moyenne(int* tab, int n)
{
double s = 0.0;
for (int i = 0; i < n; i = i + 1) {
s = s + tab[i];
}
return s / n;
}
La fonction boucle sur les valeurs d’un tableau. Il est important que la variable s soit déclarée de type
double, sinon la division finale sera une division euclidienne.
Exercice 1
Nous avons déjà vu cet exemple en cours : on peut calculer la longueur d’une chaîne de caractères en la
parcourant jusqu’à trouver un 0.
int longueur(char* chaine)
{
int i = 0;
while (chaine[i] != 0){
i = i + 1;
}
return i;
}
Exercice 2
Cet exercice vous demandait de tester des allocations de chaînes (ou de tableaux) avec différentes tailles. Ce
sont des détails qu’il est très utile de connaître, mais avant tout, c’est important de les comprendre.
Nous avons vu en cours qu’on pouvait déclarer une chaîne :
char ma_chaine[] = "decla";
La mémoire est alors allouée automatiquement avec un 0 supplémentaire à la fin.
Idem pour un tableau d’entiers :
int mon_tableau[] = {3, 0, 8, 2};
Si on précise la taille par une constante entière, il faut qu’elle soit supérieure au nombre d’éléments initialisés.
En particulier, pour une allocation de chaîne de caractères, il faut prévoir une place pour un 0 en fin de
chaîne : char mot[2] = "123" déclenchera un avertissement à la compilation tandis que char mot[3] =
"123" allouera un tableau de char sans 0 à la fin, ce qui est très mal !
À l’inverse, il est valide d’allouer plus de place :
int tableau[12] = {4, -5};
Les valeurs non initialisées seront alors mises à 0. Une manière très simple d’initialiser un tableau rempli de
0 est donc : int tab[23] = {};. Attention ! Ce n’est pas la même chose que int tab[23]; qui déclare
mais n’initialise pas. Le tableau est donc rempli de valeurs quelconques.
1
Exercice 3
Les opérations suivantes :
int a = 13;
int b = a;
a = 2;
donnent un état de la mémoire où a vaut 2 et b vaut 13. C’est parce que l’affectation de variables affecte la
valeur du membre de droite.
Maintenant, les opérations
int a = 13;
int* p = &a; // adresse de a
int* q = p;
*p = 2;
donnent un état de la mémoire où a vaut 2, tout comme *p et *q. En effet, modifier le contenu de la case
mémoire pointée par p modifie le contenu de a, qui est aussi le contenu pointé par q.
ATTENTION : p est un pointeur (de type int*), *p est un entier (de type int). L’opérateur * avant un
pointeur permet d’accéder au contenu à l’adresse donnée, et est appelé opérateur de déréférencement.
Inversement, a est un int et &a est un int* : l’opérateur & permet d’accéder à l’adresse d’une variable.
Pour la même raison, comme les tableaux sont donnés sous forme de pointeur vers la première adresse
mémoire, le code suivant
int t1[] = {-6, 42};
int* t2 = t1;
t1[1] = 9;
Laisse un état de la mémoire où t1 et t2 pointent vers la même case mémoire. Afficher t2[1] donnera donc
9, il n’y a qu’un seul tableau en mémoire.
Exercice 4
La fonction suivante teste si le tableau de longueur donnée est trié dans l’ordre croissant, en comparant les
paires successives d’éléments :
bool est_trie(int* tab, int n)
{
for (int i = 0; i < n - 1; i = i + 1) {
if (tab[i] > tab[i + 1]) {
return false;
}
}
return true;
}
Deux choses importantes à noter :
• Le return true; est situé APRÈS la boucle for. En effet, on ne conclut que le tableau est trié que
si aucune paire n’est désordonnée.
• La boucle examine les indices i allant de 0 à n - 2, et pas jusqu’à n - 1 comme de coutume. C’est
parce qu’on teste n - 1 paires, et il ne faut pas tenter d’accéder à tab[(n - 1) + 1] qui serait tab[n].
À partir de maintenant, je serai sévère si vous écrivez des fonctions qui tentent d’accéder à
l’élément d’indice n d’un tableau de longueur n !!!
2
Exercice 5
On veut recopier le contenu d’un tableau de longueur n dans un autre :
void inverser(int* source, int* dest, int n)
{
for (int i = 0; i < n; i = i + 1) {
dest[i] = source[n - 1 - i];
}
}
La fonction ne renvoie pas de valeur ; elle se contente de modifier la mémoire. Il est important de constaterqu’à
l’indice 0 dans dest, on veut mettre la valeur source[n - 1] (ET NON PAS source[n]) et donc de bien
décaler nos indices.
À faire : exercice 8.