Skip to content
Snippets Groups Projects
Théo LUDWIG's avatar
Théo LUDWIG authored
fix: better code to reverse string

See merge request !1
f3ade224
Name Last commit Last update
.gitignore
README.md
main.c

A52

Énoncé

Il est demandé à ce qu'une chaîne de caractères de longueur 10 au plus soit inversée, puis affichée.

À vous de faire la revue de code et de faire les corrections nécessaires.

gcc -Wall -Wextra -Werror main.c -o main.out

Revue de code

Constantes et éviter les valeurs "magiques"

Le code refactorisé utilise MAXIMUM_STRING_LENGTH pour définir la longueur maximale d'une chaîne plutôt que d'utiliser une valeur "magique" (10 dans ce cas).

On utilise également EXIT_SUCCESS et EXIT_FAILURE pour définir les codes de sortie du programme, plutôt que d'utiliser des valeurs "magiques" (0 et 1 dans ce cas).

Nommage des variables

Le code refactorisé utilise des noms de variables/fonctions plus explicites, comme string_reverse plutôt que my_function, temporary plutôt que temp, string_reversed plutôt que buffer pour le résultat de la chaîne inversée, index plutôt que i pour l'index de la boucle, etc.

Permet de comprendre plus facilement le rôle de chaque variable/fonction, vaut mieux éviter l'implicite, les acronymes, et abréviations, et préférer des noms explicites qui ne laissent pas de place au doute.

Séparation des Responsabilités

Le rôle du main est de récupérer l'input d'un utilisateur, d'appeler la fonction string_reverse et d'afficher le résultat.

Ce n'est pas à la fonction string_reverse d'afficher le résultat.

En séparant les responsabilités, on peut réutiliser la fonction string_reverse dans d'autres programmes qui n'ont pas besoin d'afficher le résultat sur stdout.

Responsabilité de l'allocation mémoire et Performances

Copier une variable, peut être coûteux en termes de performances, et n'est pas nécessaire dans tous les cas, en + de doubler la consommation mémoire.

Dans notre cas, on a juste besoin d'afficher la chaîne de caractères originale/d'entrée, puis la chaîne de caractères inversée. On n'a pas besoin de garder en mémoire la chaîne de caractères originale, une fois celle-ci affichée, donc on peut économiser l'allocation malloc et la copie strcpy en combinant 2 printf, un pour la chaîne de caractères originale, et un pour la chaîne de caractères inversée.

Si plus tard, on a besoin de garder en mémoire la chaîne de caractères originale, on pourra toujours faire une copie dans le main sans modifier la fonction string_reverse.

char* string_reversed = malloc(sizeof(char) * string_input_length + 1);
strcpy(string_reversed, string_input);
string_reverse(string_reversed);

// plus tard..., ne pas oublier de libérer la mémoire
free(string_reversed);

=> Les copies des variables pris en argument dans les fonctions sont à éviter, le + souvent possible, sauf si strictement nécessaire. Afin de laisser le choix à l'appelant de garder ou non la variable originale en mémoire, en faisant une copie lui-même si il le souhaite.

Séparer affichage stdout et stderr

L'affichage sur stdout est réservé aux résultats, et l'affichage sur stderr est réservé aux erreurs.

fprintf(stderr, "The string has more than %d characters.\n", MAXIMUM_STRING_LENGTH);

Documentation

La documentation est importante, elle permet de comprendre le rôle de chaque fonction, et de savoir comment les utiliser.

/**
 * @brief Reverse the characters in a string.
 *
 * NOTE: Mutates the string.
 *
 * @param string
 */

Tests Automatisés

Pour l'ajout de toute fonction/utilitaire, il faudrait rajouter des tests unitaires, afin d'éviter les régressions, et de s'assurer que le code fonctionne comme prévu.

Le mieux serait de le faire dans un fichier à part, qui contient uniquement les tests, et qui n'est pas compilé dans le programme final, de "production".

Ici il faudrait tester la fonction string_reverse.