Choisir entre deux fonctions

Le problème exposé dans ce sujet a été résolu.

Bonjour,

Dans le cadre du cours sur le C, il y a un exercice qui demande de vérifier si un mot est oui ou non un palindrome. Pour pousser l’exercice plus loin, j’ai essayé de faire fonctionner la fonction avec toutes les chaînes de caractères possibles, et pour cela, je dois entre autres ne pas tenir compte des accents, des majuscules, des trémas, etc..

J’ai donc écrit une fonction pour changer une chaîne de caractères fournie de façon à ce que les accents et autres soient supprimés :

 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
char norm_char(char c){
    if(c >= 65 && c <= 90)
        return tolower(c);
    else if(c == 129 || c == 150 || c == 151 || c == 154 || c = 163)
        return 'u';
    else if(c == 131 || c == 132 || c == 133 || c == 134 || c == 142 || c = 143 || c == 160 || c == 166)
        return 'a';
    else if(c == 130 || c == 136 || c == 137 || c == 138 || c == 144)
        return 'e';
    else if(c == 128 || c == 135)
        return 'c';
    else if(c == 139 || c == 140 || c == 141 || c == 161)
        return 'i';
    else if(c == 147 || c == 148 || c == 149 || c == 153 || c == 162 || c == 167)
        return 'o';
    else if(c == 152)
        return 'y';
    else if(c == 164 || c == 165)
        return 'n';
    return c;
}

int to_norm(char * str, size_t size){
    int i;
    unsigned int char_changed = 0;
    for(i = 0; i < size -1; i++){
        if(str[i] != norm_char(str[i])){
            str[i] = norm_char(str[i]);
            char_changed++;
        }
    }
    return char_changed;
}

Mais pour écrire la seconde, je me suis dit que ça serait plus simple si je changeais la première de façon à recevoir directement l’information ’le caractère a été changé’. J’ai donc écrit une autre fonction :

 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
int norm_char(char *c){
    if(*c >= 65 && *c <= 90)
        *c = tolower(*c);
    else if(*c == 129 || *c == 150 || *c == 151 || *c == 154 || *c == 163)
        *c = 'u';
    else if(*c == 131 || *c == 132 || *c == 133 || *c == 134 || *c == 142 || *c == 143 || *c == 160 || *c == 166)
        *c = 'a';
    else if(*c == 130 || *c == 136 || *c == 137 || *c == 138 || *c == 144)
        *c = 'e';
    else if(*c == 128 || *c == 135)
        *c = 'c';
    else if(*c == 139 || *c == 140 || *c == 141 || *c == 161)
        *c = 'i';
    else if(*c == 147 || *c == 148 || *c == 149 || *c == 153 || *c == 162 || *c == 167)
        *c = 'o';
    else if(*c == 152)
        *c = 'y';
    else if(*c == 164 || *c == 165)
        *c = 'n';
    else
        return 0;
    return 1;
}

int to_norm(char * str, size_t size){
    int i;
    unsigned int char_changed = 0;
    for(i = 0; i < size -1; i++){
        if(norm_char(&str[i]))
            char_changed++;
    }
    return char_changed;
}

Mais je me pose la question : Y en a t-il une ’mieux’, et pourquoi ?

+0 -0

En général, quand on se retrouve avec deux fonctions qui font la même chose (ce qui arrive quasiment jamais, avouons-le), on privilégie celle qui semble la plus propre, et à defaut ou dans certains cas particuliers, la plus rapide.

+0 -0

De manière générale, il est mieux d’éviter d’avoir des données que l’on modifie. Tes deux implémentation de to_norm ont la même "interface" et ont une implémentation similaire, donc on peut considérer qu’elles sont équivalentes. En revanche, ta première implémentation de norm_char n’a aucun effet de bord et est donc préférable.

De manière générale, il est recommandé si possible d’éviter d’avoir des données mutable. Autant sur des petits projets ça ne se remarque souvent pas trop, mais dès que tu veux faire des choses un peu plus complexes, devoir gérer des données mutable devient de plus en plus difficile et peux augmenter drastiquement les risques d’avoir des bugs. Ne serais-ce qu’en terme de compréhension du code, si tu appelles une fonction qui peux modifier les variables que tu lui donnes il sera plus difficile de comprendre comment elle interagit avec le reste du code que si elle ne modifie pas ses entrées. Il y a deux choses importantes que tu peux avoir avec des données non modifiables: l’ordre d’appel des fonction n’a pas d’importance et appeler une fonction plusieurs fois a le même effet que l’appeler uniquement une fois. Ce sont des propriétés très intuitives: si tu calcules a + b et b + c, l’ordre de calcul ne devrait pas affecter le résultat. De même, si tu calcules deux fois a + b, tu devrais avoir le même résultat les deux fois.

Pour en revenir à ton problème initial, plutôt que de modifier ta chaîne de caractère pour ensuite appliquer une fonction qui teste si elle est palindrome ou non, il serait beaucoup plus propre de créer une fonction qui test si une chaîne de caractère est palindrome en utilisant une fonction d’équivalence générique plutôt qu’une égalité strict.

En gros, dans ta fonction de test il faudrait remplacer if(c1 == c2) par if(equals(c1, c2)) et ensuite choisir equals selon ce que tu veux. Le gros désavantage de cette technique est que si tu veux utiliser deux fonctions d’équivalence dans ton code, tu sera obligé soit de faire un copier-coller du code en modifiant la fonction d’équivalence, soit d’utiliser les techniques que tu n’as probablement pas encore abordé dans tes cours (pointeurs de fonctions ou macros).

Image utilisateur mon problème c’est comment créer un programme de cette image qui affiche les points qui touche puis affiche le score

CherniMaha

Salut, si ton problème n’a pas de rapport avec celui de Arthur tu doit faire un nouveau topic (parce que tu coup là t’es en hors sujet donc tu n’auras pas de réponse et ton message sera très probablement masqué par un modo). :)

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte